I'm investigating a vulnerability in an application that echoes a user-supplied filename without sanitizing the filename.

E.g. a file named test-<script>alert("evil");.txt will result in that text echoed into the XHTML. (In case it matters, this particular document is served as text/html and the doctype is xhtml1-transitional.)

The problem is that the <script> tag can't be closed because the filename can't contain a /. This means that the script isn't executed because everything that follows is part of the script, and all that HTML will be invalid JS.

(FWIW, I'm also investigating the use of subdirs as a way of getting the slash into the application, but it appears to trim the dirname from the file before displaying. Heh -- having a file named ./<script>alert("evil subdir?");</script>.txt makes me feel a little queasy...)

Based on a few XSS cheat sheets, I've tried several ways of encoding the slash so that it can appear in the filename but still be interpreted by the HTML parser as a closing tag. No luck; the characters are inserted literally into the HTML without any intermediate encoding/decoding.

Even without the slash I've found three or four ways of exploiting it, but so far they require user interaction with that element (e.g. onmouseover). They also make the page ugly because the tag structure falls apart. If I can close the tag, the exploit is both invisible and automatic.

Are there any standard (i.e. XSS filter evasion) techniques for closing a tag without quotes that I'm missing?

1 Answer 1


Here are some more you can try. I betcha that one of these will work (in fact, I bet that the first one will work, and then you can stop reading):

  • Try <img src="" onerror="alert(0)">. No user interaction involved.

  • You're giving up too easily on onmouseover. Create a giant element that covers most of the page, and then use onmouseover. While technically user interaction is involved, I think you can make it almost automatic.

  • Try onreadystatechange, e.g., <iframe onreadystatechange=alert(0)>. It is IE-only (IE7 and later, I think) but powerful.

  • Try onfocus="alert(0)" autofocus, e.g., <input autofocus onfocus=alert(0)>. I don't know if this will work.

  • On Opera, try <table background=javascript:alert(0)>. It might work.

  • Try <img src="javascript:alert(0)"> and <iframe src="javascript:alert(0)"> (unlikely to work on most browsers, but you can try it).

  • If the server doesn't specify the content-encoding type in the headers of the HTTP response, try UTF-7 shenanigans (only works on older browsers).

Note that these techniques are likely to be highly browser-dependent.

If you are still stuck, try asking on Sla.ckers; there are a bunch of folks who hang out there who are super knowledgeable about this sort of thing. For the basics, I recommend RSnake's XSS cheat sheet. For more advanced XSS vectors, try Gareth Heyes' blog and Sla.ckers.

  • Well, I didn't stop reading, but the first one did the trick. The server does specify the content-encoding, so the last one won't work. I'll keep the other techniques in mind. The onerror trick is perfect for where the filename first occurs in the page -- inside an <option> in a pulldown.
    – bstpierre
    Nov 18, 2011 at 19:09

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .