Following on from my first blog post, hopefully you’ve now grasped the basics of XSS, so we can move onto some slightly more advanced areas. As mentioned in the previous post, we’ll be covering event handlers today. We’re also going to take a look at breaking out of HTML tags, as this is another essential part of exploiting XSS flaws and web security!
<a onmouseover=alert('Boom')>Hey there</a>
That’s right, when you move your cursor over the Hey there that’s displayed on the page, an alert box will pop up.
From an XSS perspective, we can loosely categorize these event handlers into two types, those that require user interaction to trigger and those that don’t. We will take a look at both below.
Example 1: Event Handlers that Require User Interaction
We can demonstrate this with the DOM based XSS WebGoat example described in the previous blog post. We insert the above onmouseover event handler string and when we hover our mouse over it…
Boom! Pop up time! As the event handler constantly listens for the corresponding event we do not need to refresh the page, like we would if using script tags. Note, we need the HTML <a> tags as they will anchor our text. Other tags will work as well, such as <p>, the paragraph.
We can see the event handler in the source if we try it in the DVWA reflected XSS challenge:
Other types of event handlers like this are:
As mentioned above, the issue with these types of event handlers is that they require some sort of interaction from the user, increasing the amount of coercion required for a successful XSS. There are a few, however, that don’t.
Example 2: Event Handlers that Require No User Interaction
For this example, let’s try it with the reflected XSS scenario in DVWA. We’ll be using this event handler string:
<img src=xss.png onerror=alert('Boom!')>
The img src tries to load an image called xss.png, which clearly won’t exist on the server. As a result, it will produce an error, but we’ve added a handler for that event, the onerror, which will pop an alert box displaying Boom!. Let’s give it a go!
In all the above examples, we’ve been injecting our scripts into areas where our code is executable by the browser. More often than not, however, you’ll be injecting into <value = ” ” /> tags, or <textarea></textarea> tags, in which the browser will consider any code to be text and will thus not execute it. Therefore, we have to break out of these parameters by closing off the HTML tags before we insert our script. For example, consider this line of the code, taken from the registration page of a large website (source for this find and the others below are the Reddit XSS page):
<input type="text" name="email" size="30" value="email@example.com" />
If we then enter our standard XSS string <script>alert(‘Boom!’)</script>, the source will read:
<input type="text" name="email" size="30" value="<script>alert('Boom!')</script>"/>
As you can see, our script is totally contained within the value tag, so it won’t be executed by the browser. Thus we have to break out! To do so, we will prepend “/> to our script, so that when our browser reads the source, it will think the value tag has been closed gracefully. So we enter
And the source becomes:
<input type="text" name="email" size="30" value=""/><script>alert('Boom!')</script>"/>
We have now closed off the value tag so our script is nicely nestled in the page, outside of the value tag, which means popup time! The trailing “/>, left there from the original HTML, will be ignored by the browser as it has no corresponding opening tag (as we added our own closing tags for the value parameter).
A similar concept applies to <textarea> tags; consider this example taken from the search function of another website:
<textarea name="query" id="query" class="tap_newtext" onkeydown="charCount();submitTranslateForm(event);" onkeyup="charCount();">search term here</textarea>
We can ignore most of the HTML here (notice the event handlers though?) and skip to the end where we have our search term and then the </textarea>tag. Again if we enter our basic script in, it will be contained within the <textarea> tags and so won’t be executed by the browser. So no prizes for guessing what we need to do… just prepend </textarea> to our script!
<textarea name="query" id="query" class="tap_newtext" onkeydown="charCount();submitTranslateForm(event);" onkeyup="charCount();"></textarea><script>alert('Boom!')</script></textarea>
And once more it’s popup time! As above, the last </textarea> tag will be ignored as it has no corresponding opening <textarea> tag.
As you can see, we’re injecting into a script already so what we have to do is close off the script, using </script>, then insert our own script, making it:
And we get our final popup!
You must be getting pretty tired of simply popping up alert boxes by now so in my next post we will be looking at some of the more malicious activities we can perform with XSS, such as page redraws and credential harvesting. Check back soon!