When reading material on XSS subject we usually see the classical <script>alert(1)</script> as an demonstration of such vulnerability (PoC – Proof of Concept). While very true, it doesn’t go much beyond this, making the novice in this field to look for more in order to deal with real world scenarios.
So here are the 7 cases everyone should know to be able to exploit the vast majority of XSS flaws out there. A web page to show them with their variations (single or double quotes) was built to training (click to go to it):
Right in the beginning of the source code, there’s a HTML comment with all parameters to trigger each case. All of them work for both GET and POST requests.
As you might notice, all cases are source-based which means that injection always appears in source code retrieved in the body of an HTTP response. Independent of being of reflected or stored type, important here is the context where they appear when DISPLAYED so we will always use the reflected one as main example. There are XSS flaws that don’t appear in source code, the DOM-based ones, which won’t be covered here.
Remember to try examples below only in a browser without native XSS filtering, like Mozilla Firefox.
1. URL Reflection
When URL is reflected somehow in source code, we can add our own XSS vector/payload to it. For PHP pages it’s possible to do add anything in the URL after page name (without changing it) with the use of a slash character (/).
The leading tag breaking (“>) is needed to break out of the current tag an make possible the insertion of a new one.
Although there are several reasons for different languages (reflection might appear in path or in URL parameters too), for PHP the culprit usually is the global variable $_SERVER[“PHP_SELF”] in action field of submission forms.
2. Simple HTMLi (HTML injection)
The most straightforward one, input is reflected just right in the code between existing tags, after or before them. Without the need to escape or break anything, any simple XSS vector like the ones in the form of <tag handler=jsCode> does the job.
3. Inline HTMLi
Almost simple as the previous one but with a little “> prepended to break out of the current tag.
4. Inline HTMLi: No Tag Breaking
When input lands in an HTML attribute and there’s filtering of greater than character (>), it’s not possible to break out of current tag like in the previous case.
So we use an event handler appropriate to the very tag we are injecting into, like:
Which closes the value and gives room to insertion of the onmouseover event handler. Pointing to alert(1) followed by double slashes to comment out the hanging quote, that triggers the js popup when victim points his/her mouse over the affected input field.
6. Simple Js Injection
If the script tag is being filtered somehow, previous exploitation will fail.
7. Escaped Js Injection
In the previous case, if the quote (which is responsible for the break out of the variable’s value) is escaped with a backslash (\), injection won’t work (invalid syntax).
For that, we have a little trick: escaping the escape. We insert a leading backslash to escape the added one and then the quote will work to break. After “concatenation” to our desired js code, we need to comment out the rest because there’s no way to repeat the process in the remaining side of the injection.