X-Content-Type-Options: nosniff header

Over the past two months, we’ve received significant community feedback that using a new attribute on the Content-Type header would create a deployment headache for server operators. To that end, we have converted this option into a full-fledged HTTP response header.  Sending the new X-Content-Type-Options response header with the value nosniff will prevent Internet Explorer from MIME-sniffing a response away from the declared content-type.

For example, given the following HTTP-response:

HTTP/1.1 200 OK
Content-Length: 108
Date: Thu, 26 Jun 2008 22:06:28 GMT
Content-Type: text/plain;
X-Content-Type-Options: nosniff

<html>
<body bgcolor=”#AA0000″>
This page renders as HTML source code (text) in IE8.
</body>
</html>

Browsers sniff mime types of HTTP responses, initially because page authors frequently don’t get them right* and now because browsers have done it historically.

The worst instance related to mime sniffing is an old IE bug. As I understand it their sniffer tried some image formats and then HTML; then when they added PNG sniffing it was added to the sniff list after HTML, either by mistake or to maintain compatibility with pages that were currently being sniffed as HTML. The result of this is that even valid PNG images can be sniffed as HTML, converting a user-uploadable image into a Javascript (XSS) vector. The Chromium mime sniffer‘s comments (which are quite readable, and tabulate various browsers’ behaviors) describe this as a “dangerous mime type”.

But there are plenty of other ways that sniffing can screw you as a site author. Your only defenses if you’re building a site are:

  • either make sure user-uploaded images are on a different origin than your site’s cookies;
  • or set the Content-disposition: attachment header, preventing people from displaying the image in their browser.

I believe this bug is why you cannot view images attached to gmail messages — if you click “view image” in gmail you instead get an HTML page with an <img> tag, and if you right-click on that image and pick “view image” you’ll get it served with the attachment header.

To solve this mess, IE introduced the X-Content-Type-Options: nosniff header, which means “don’t sniff the mime type”. It looks like a reasonable workaround to me: it lets new pages opt into sane behavior without breaking old ones. Chromium added support for it.

It sounded good to developers of a Google-internal HTTP server as well; they added it by default to all responses. And then the bug reports started coming in: “Why does my page render in all browsers but Chromium?” It turned out many of these sites were sending no Content-type header, which, when coupled with the nosniff header, meant Chromium would pick the default of application/octet-stream, triggering a download box.

The fix is to match IE (r8559) for this corner case, which is to instead default to text/plain; I made wisecracks about adding an X-Content-Type-Options-Options: no-really-none-of-these-mime-shenanigans header. Adam (master of content-type sniffing, and I believe editor of the HTML5 sniffing spec) also wrote r8257. This collects stats (aggregated anonymized and only from users who have opted in) on what fraction of pages that we normally would’ve sniffed but were instead blocked by the header.

* In fairness, the greater problem is that page authors sometimes don’t control HTTP headers. They’re frequently defined by server configuration, which often requires root on the server or at least a lot more technical know-how than “click on the upload button in your website creator program”


Posted

in

, , , ,

by

Tags:

Comments

5 responses to “X-Content-Type-Options: nosniff header”

  1. DrLex Avatar
    DrLex

    The WAP browser on my phone mistakes the ‘X-Content-Type-Options’ for an ‘X-Content-Type’ header, making each and every page served with that header completely unusable. In other words, the entirety of Google is unusable on my phone. Thanks, Microsoft (and the lazy programmers of my phone).

    Like

  2. lucky Avatar
    lucky

    I want to apply the same thing for iframe in html. but no luck

    Like

  3.  Avatar
    Anonymous

    For those people who would like to know how to enable server to respond with nosniff header. Here is a tutorial :
    http://www.pwnphreak.com/blog/2012/12/13/x-content-type-optionsnosniff-header-missing/

    Like

  4. […] a good article on the reason for the nosniff header here :https://htaccess.wordpress.com/2009/09/22/x-content-type-options-nosniff-header but in short it’s a directive from IIS that tells the browser to not sniff the MIME type. I am […]

    Like

  5. […] See Scott Holme’s brief description of X-Content-Type-Options or another post with more details on the problem. […]

    Like

Leave a comment