It's always nice to see a manager or developer fully understand the severity of cross-site scripting (XSS). Displaying user-supplied input without sufficient encoding can have a serious impact on a web application – in particular, its users may become vulnerable to remote session hijacking, autocompleted passwords could end up being covertly siphoned off to the attacker, and most CSRF (cross-site request forgery) protection mechanisms can be bypassed.
However, those who do understand the risks of XSS may nonetheless dismiss the possibility of such nefarious attacks if the vulnerable input parameter is truncated to less than 30 characters or so. After all, how can you steal a password in less than 30 characters?
XSS in 10 characters (well, 27 really)
Many web application security testers will demonstrate an XSS vulnerability
by injecting something like
<script>alert(123)</script> into a webpage. This
will cause a dialog box to pop up and display the message "123".
Unfortunately, that's the kind of benign demonstration that makes a manager think, "So what?"
Demonstrations are much more powerful if they show something bad happening, but how can that be done if we've already reached the maximum length (27 characters) of the vulnerable input parameter?
After the overhead of the
script tags (of which there must be both an opening and closing one), there is only room to inject 10 characters
Bootstrapping larger XSS payloads
window.name attribute, which is practically unlimited in size:
window.name = "var x=1; do_some_bad_stuff(); [...] ";
When the victim uses the same browser tab to view the vulnerable website, the payload will remain accessible via the
window.name attribute. In practice, this is most likely to be exploited through the use of a hidden iframe, which sets the payload from the attacker's site, and then automatically redirects the iframed window to the vulnerable page on the target site.
I'm not aware of an XSS vulnerability that can be exploited in fewer than 10 characters, so let me know if you find one! Note that the example above requires 27 characters if you include the
If a web application displays user-supplied input without sufficient encoding, it would generally remain safe from cross-site scripting attacks if the maximum length of the input is restricted even further than in the previous examples.
This can be demonstrated by the following vulnerable HTML template, which fails to encode the name and telephone numbers after a user submits some feedback:
<p> [ $name ] - thanks for submitting your comments. Your feedback is important to us. As requested, we will contact you about this issue as soon as possible, using the contact details provided below: </p> <ul> <li>Landline: [ $tel1 ]</li> <li> Mobile: [ $tel2 ]</li> </ul>
The user name is limited to 16 characters in length, while both of the telephone numbers are limited to 12. Although each individual field is too short to allow a practical XSS attack, the vulnerable fields can effectively be chained together by submitting the following values:
$name: <script>alert(/* $tel1: */'XSS'/* $tel2: */);</script>
<p> <script>alert(/* - thanks for submitting your comments. Your feedback is important to us. As requested, we will contact you about this issue as soon as possible, using the contact details provided below: </p> <ul> <li>Landline: */'XSS'/* </li> <li> Mobile: */)</script></li> </ul>
Big or small, gotta fix 'em all.