Running an XSS attack from an image

Edit: This has since been resolved in IE7, so the vulnerability described here is no longer a threat except to old versions of IE.

A cross site scripting attack is where you get JavaScript to run from within the context of a website that isn't yours. It's usually used to retrieve the cookies of a user of that website, which the browser will only send to the website that created it, and using JavaScript to send those cookies to another website which couldn't otherwise access them. Most often these cookies are used for authentication, and they allow an attacker to log on as the victim on the website that was exploited.

XSS attacks occur when input isn't checked enough. If you allow anyone to post to your website without checking the input they can easily add

<script> // Do bad things </script>

These are easy enough to thwart with simple functions like htmlentities, but there can often be holes where not all input is checked or checked thoroughly enough. A famous MySpace XSS attack by Samy exploited the way that Internet Explorer is relaxed about what can be interpreted as JavaScript, and this is similar.

Internet Explorer doesn't go on the mimetype the web server gives it; if a web server tells IE to expect an image IE will check out the image to make sure that it isn't actually a web page. The signs IE looks for that something is an image and not a web page are HTML tags anywhere within the image.

If you put <script>alert("Scripted image.");</script> in the comment of an image IE6 will think it's an HTML document, and execute the script. You have to open the image by itself and not look at it from inside another webpage, or IE does not check the image for HTML.

That works okay and can run JavaScript, but even a script that doesn't output anything would look suspicious because the image isn't displayed as an image but as a webpage because IE recognises the mimetype differently, resulting in garbled text. By making a script that replaces the garbled text as an actual image you can run a script without it being clear that you have.

<script>function a() { document.write("<img src='image.png'></img>"); }; window.onload = a; alert("Hidden scripted image.");</script>

The script above could let an attacker retrieve cookies without being noticed. It looks normal in non-IE browsers (but won't execute) and in IE browsers it will execute the code before overwriting it with a link to another image, in this case the image itself (it doesn't cause a recursive look because script is not executed in images that are embedded in webpages).

The main worry with this is that the script containing images are perfectly valid as images, and you can't use generic detection code against the images since they are binary. You have to explicitly look for various html tags within the start of images before allowing them to be viewed, and this is unlikely to be done since it's not well known about. Wherever a website has image upload this problem often goes unchecked.