Does X-Content-Type-Options really prevent content sniffing attacks?

Background. X-Content-Type-Options: is a header that is designed to defend against MIME content-sniffing attacks. MIME content-sniffing attacks are a risk when you allow users to upload content (e.g., images, documents, other files) to your website, where they can be downloaded by other users.

As @Rook says, this has nothing to do with eavesdropping/capturing network traffic.

What attacks doesn't it prevent? Because X-Content-Type-Options: is only supported on some browsers, it does not protect attacks against users who use other browsers. In particular, it is supposed on IE, Chrome, and Firefox 50. See also What are the security risks of letting the users upload content to my site? for some other attacks it doesn't prevent, e.g., uploading of malware or unsavory content, uploading of content that exploit a vulnerability in the user's browser, etc.

What content type should be returned? You should return the appropriate content type for that file. You should not allow users to upload untrusted content with dangerous content types. For more details, please see the answers to the following questions:

  1. Is it safe to serve any user uploaded file under only white-listed MIME content types?

  2. Is it safe to store and replay user-provided mime types?

  3. MIME sniffing protection

  4. Why should I restrict the content type of files be uploaded to my site?

  5. What are the security risks of letting the users upload content to my site?

  6. How can I be protected from pictures vulnerabilities?

  7. Using file extension and MIME type (as output by file -i -b) combination to determine unsafe files?

This topic has been extensively discussed and documented elsewhere on this site, so I'm not going to try to repeat all of the useful advice found there.


Update: I just learned that setting the Content-Type and X-Content-Type-Options headers appropriately is not enough for security. Apparently, Flash ignores the Content-Type header, which could allow loading a malicious SWF, which can then do everything you'd do with a XSS. (Sigh, stupid Flash.) Unfortunately, no amount of whitelisting of file content types can stop this attack. Consequently, it appears that the only safe solution is to host the user-uploaded content on a separate domain.


Here is an answer of Michal Zalewski received by email:

The short answer is that it works in MSIE, and only in some specific cases. It won't protect you against (much less zealous) sniffing in most other browsers; but more importantly, won't discourage plugins from doing things such as the crossdomain.xml risk outlined above; and won't necessarily prevent subresource loads with mismatched MIME types (i.e., loading an image as application/x-shockwave-flash via <embed>).


What sniffing attacks X-Content-Type-Options:nosniff doesn't prevent?

Sniffing by tools that don't know about X-Content-Type-Options: some browsers, and plugins that can fetch network resources. (For example historically Java GIFAR, Flash loadPolicyFile...)

What Content-Type should be returned to user instead of text/plain?

There is no good answer to that, so if you need to host untrusted text files you should take the usual mitigation of hosting them on a separate hostname (and ideally IP address).

Alternative: HTML-encode, add a <pre> and serve as text/html.