Recently we got many bug reports about problems with the IE8 beta browsers. The problem is that we cannot accommodate beta browsers in our software – the next beta will break our adjustments. But why have we chosen to include some other IE8 features? The answer is simple: security
This post will give you insights into one of the more obscure security implications of file uploads.
The History so far
Back in 2006 a new kind of XSS vector started to circulate on the internet: HTML code in broken GIF pictures. For some reason, the Internet Explorer browser – then in version 6 – would render HTML in image files with an incorrect header. To have this behaviour, it was enough to visit the file directly, i.e. not the containing HTML page, with the browser – an attacker would have to make the victim click a link.
Such files could be files with the .gif extension featuring a png header in the file. Or it could be just plain broken image files. phpBB2 and 3 were inoculated against this sort of attack by using the getimagesize function to make sure that the file contents agrees with the extension. All was considered to be good.
However in early 2007, we were notified by ahingert about an interesting phenomenon: IE also rendered HTML in broken files with a valid png header and the .png extension. Even worse, research by Pit unveiled that completely valid .png files would be treated as HTML, if the bytepattern resembled certain HTML tags. We found out that this behaviour was not limited to png files, but also affected almost all image extensions other than .gif and .jpg and – alarmingly – .txt.
Faced with this discovery, we implemented radical changes in phpBB3. In earlier versions, avatars and attachments (if publicly readable) were delivered directly by the server without using a php instance. Faced with the security hazard posed by this practice, we removed the direct delivery and instead forced all files, including avatars, to be delivered via the attachment system. To tighten this up, we changed the naming scheme of the files on the server to stop attackers from guessing them.
Moreover we changed the headers: for IE users all files are delivered with the attachment content-disposition to hinder them from rendering in the page context. So, if you wonder why avatars have weird names on the server: that’s why.
Naturally, we also investigated the reason behind it. We quickly found out that we were experiencing a feature: Mime sniffing. Sadly, the documentation provided by MS turned out to be almost completely incorrect.
We contacted Microsoft about the issue. Techie-Micheal exchanged several letters with the MS security staff, who silently – without any mention in docs or patchday announcements – disabled mime sniffing for png files.
We went even further with the release of phpBB 3.0.2. Using a list of strings able to cause mime sniffing compiled by Nicolas Grekas and double checked by ourselves, we added the option to block all uploads that would be seen as HTML by IE. The forbidden byte patterns are:
- Code: Select all
- <!–
As we were not the only web developers having trouble with uploads, but had our resentments echoed by MediaWiki and others, MS finally added a proprietary header to disable mime sniffing in IE8 Beta 2.
Nice text, but can you give us an example?
Sure. You can even easily make one yourself :
- Code: Select all
alert('mime sniffing in action'); // -->
Save that as .txt file, upload it to your server and visit it with different browsers. Note the difference?
To really show the difference: click this image with IE (and another browser for comparison)
Scary, eh?
What happens? Well, the image’s byte pattern in the first 255 bytes happens to be exactly like certain HTML tags, despite also being a valid bitmap. IE sees that and decides to handle the “image” as html. IE does this, because it doesn’t know how to handle the “image/bmp” content-type sent by our server. However, that (arguably incorrect) type is sent by default apache and php installations for bmp files.
What can you do about it
Let’s start with the good news: if you limit the uploads to png, gif and jpeg and validate with getimagesize, you should be fine. Otherwise, you have to jump through many hoops.
Internet Explorer 6
This is the worst case. To stop IE6 from doing terrible mistakes, you have to be rather restrictive.
- Use getimagesize to make sure that file and mime type agree
- Set the content-disposition: attachment header
- Completely forbid any caching from happening (otherwise the back button will lead to XSS)
- Try to avoid uploads containing HTML tags.
- Stop users from accessing images directly; wrap them in HTML img tags.
- If the IE version is unpatched, it will also do funny things with .png – beware
The phpBB attachment handling will do all this for you.
Internet Explorer 7
IE 7 behaves somewhat nicer, as we are able to allow caching. Otherwise it is still not pretty:
- Use getimagesize to make sure that file and mime type agree
- Set the content-disposition: attachment header
- Stop users from accessing images directly; wrap them in HTML img tags.
- Try to avoid uploads containing HTML tags.
- If the IE version is unpatched, it will also do funny things with .png – beware
The phpBB attachment handling will do all this for you here as well.
Internet Explorer 8
Okay, IE8 Beta2 has new headers. This is the one feature of IE8 we are already using, as we trust the IE team to keep it and because it vastly improves the usability.
- Use getimagesize to make sure that file and extension agree
- Add authoritative=true to the Content-Type header. i.e.
- Code: Select all
Content-Type: text/plain; authoritative=true
- Set the “X-Download-Options: noopen” header for all non-image files to stop IE from rendering HTML in context.
This will be part of the next phpBB 3.0 release
Is there any other way?
For image files there is one other useful precaution: use GD or imagemagick to remake the image files in a “safe” format like jpg. The advantage is that you can will not have to do awkward header setting on the file delivery. The downside is that you will expose these applications/libraries to attackers. If you chose to use this defense, make sure that your server setup is always up-to-date. Another problem is: these tools are not available on all hosts.
For text files, possibly the file type nobody wants to render as HTML, there is also the option of buffering the files with 256 bytes of “safe” data.
UPDATE: heise security now has an article by yours truly about the matter. The English version still needs some polish, I am not sure when I will get aorund to it.
Posted by rma-web on October 25th, 2008 at 9:14 pm:
wow, thats scary. i dont know why people use IE anymore, firefox is a lot safer to use.