Back to HTTP Headers

X-Content-Type-Options security response

Stops browsers from guessing the content type and forces them to use what the server declared — preventing MIME sniffing attacks.

What it does

X-Content-Type-Options with the value nosniff tells the browser: "Trust the Content-Type I declared. Don't try to guess the content type by sniffing the response body."

Without it, browsers — particularly older versions of Internet Explorer — would ignore the declared Content-Type and guess the type from the content itself. This created an attack vector: an attacker could upload a file declared as text/plain that actually contained HTML and JavaScript. When a browser sniffed it and decided "this looks like HTML," it would execute the JavaScript.

Syntax

X-Content-Type-Options: nosniff

There is only one valid value: nosniff. The header without this value, or with any other value, has no effect.

MIME sniffing attacks

The attack without nosniff:

  1. An attacker uploads a file to your server (e.g., a profile picture)
  2. The server stores it and serves it as Content-Type: image/jpeg
  3. The file actually contains <script>alert(document.cookie)</script> embedded in it
  4. An older browser sniffs the content, decides "this looks like HTML," and renders it — executing the script in your origin's context

With X-Content-Type-Options: nosniff:

  • The browser respects Content-Type: image/jpeg and renders it as an image (or fails to render it if the bytes don't match JPEG)
  • The script never executes

What nosniff actually does

The spec defines two specific blocking behaviours:

For scripts: If the Content-Type is not a JavaScript MIME type (text/javascript, application/javascript, etc.) and nosniff is set, the browser refuses to execute the resource as a script, even if a <script src="..."> points to it.

For stylesheets: If the Content-Type is not text/css and nosniff is set, the browser refuses to apply the resource as a stylesheet, even if a <link rel="stylesheet"> points to it.

This also protects against serving JavaScript/CSS from CDNs or file storage services that might not set Content-Type correctly.

Should I always set this?

Yes. There is no legitimate use case for allowing MIME sniffing. The only "cost" is that your server must set accurate Content-Type headers — which it should be doing anyway. Setting X-Content-Type-Options: nosniff on every response is a zero-downside security improvement.

It's one of the three headers (alongside X-Frame-Options and Strict-Transport-Security) that security scanners, pen testers, and compliance frameworks uniformly require.

How it interacts with other headers

X-Content-Type-Options: nosniff enforces Content-Type. Without accurate Content-Type headers, nosniff can break legitimate resources. If you have a JavaScript file served without a Content-Type or with a wrong type, adding nosniff will prevent it from loading as a script.

CSP's script-src and style-src also restrict what can be loaded as scripts and styles by origin — nosniff restricts by content type. Both layers are complementary.

Common mistakes and gotchas

Serving assets without Content-Type and adding nosniff. A file storage service or CDN bucket that serves files without Content-Type headers will start breaking JS and CSS loading after you add nosniff. Audit your content types before deploying.

Applying it selectively. Some setups apply nosniff only to HTML pages and not to API or asset responses. Apply it universally — it's simpler and more secure.

Confusing it with CSP. They're complementary. CSP script-src says "scripts can only come from these origins." nosniff says "resources will only be interpreted as the type declared." Both are needed.

Real-world examples

Standard secure response headers:

HTTP/1.1 200 OK
Content-Type: text/html; charset=UTF-8
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
Strict-Transport-Security: max-age=31536000

API response:

HTTP/1.1 200 OK
Content-Type: application/json
X-Content-Type-Options: nosniff

FAQ

Does X-Content-Type-Options protect modern browsers?

Modern Chrome, Firefox, and Safari have largely eliminated aggressive MIME sniffing regardless of this header. But setting nosniff still matters for: IE and Edge Legacy users, consistent cross-browser behaviour, security compliance requirements, and protection against future browser changes. The header is cheap — always set it.

Can nosniff break my site?

Only if your server is serving resources with incorrect or missing Content-Type headers. In that case, the fix is to set the correct Content-Type, not to omit nosniff. Think of it as surfacing a pre-existing misconfiguration.

Does this affect image loading?

For images, nosniff does not block loading based on content type mismatch in most browsers — the spec primarily targets scripts and stylesheets. Images with wrong content types may still load. The protection is mainly about preventing script/style execution from incorrectly typed resources.

Fun fact

X-Content-Type-Options was introduced by Microsoft in Internet Explorer 8 in 2008 — the same browser that popularised the aggressive MIME sniffing it was designed to prevent. IE was notorious for its content sniffing heuristics, which would examine the first 256 bytes of a response and override the declared Content-Type if the content "looked like" something else. The vulnerability was so prevalent that Microsoft essentially had to ship a header to disable their own browser's behaviour. The X- prefix indicates it was a non-standard extension at the time; it was never officially standardised but became universally adopted.