X-Content-Type-Options: nosniff and MIME sniffing
X-Content-Type-Options: nosniff tells the browser to trust the declared Content-Type instead of guessing from the bytes, which stops an uploaded file being treated as a script.
At a glance
- Direction
- Response only. The token nosniff is the only defined value.
- Defined in
- The Fetch standard (WHATWG)
- When absent
- The browser may sniff the body and override your Content-Type when the bytes look like something else.
- Valid values
- nosniff. Anything else is treated as if the header were absent.
- Blocks
- Scripts and stylesheets whose declared type does not match how they are used
- Risk of adding it
- Low, unless a resource is being served with the wrong Content-Type today
- In the headers checker
- Graded. It warns unless the value is exactly nosniff.
In detail
Without this header a browser is allowed to look at the first bytes of a response and decide the server was wrong about the type. That behaviour exists for historic compatibility and it is dangerous on any endpoint serving user uploads: a file stored as text/plain but starting with markup can end up parsed as HTML, in your origin, with access to your cookies.
nosniff makes the declared Content-Type binding in two specific places. A script whose type is not a JavaScript media type is refused, and a stylesheet whose type is not text/css is refused. For images, fonts and downloads the header mostly stops the browser inventing a type that would let the content run.
Turning it on is the cheapest of the common security headers, but it does surface existing mistakes. If a build step serves JavaScript as text/plain, or an asset host answers with application/octet-stream for everything, those resources stop loading the moment you add nosniff. That is the header working correctly, and the fix belongs in the Content-Type of those responses.
The value is a single token with no scope, path or wildcard syntax. Send it on every response rather than only on HTML, because the resource being protected is the script or the stylesheet, not the page that references it.
Examples
X-Content-Type-Options: nosniffHTTP/1.1 200 OK
Content-Type: text/plain
X-Content-Type-Options: nosniff
console.log('loaded with a script tag, and blocked because of the content type');The same response without the header would very likely be executed anyway.
Things that catch people out
- The value is one word. X-Content-Type-Options: nosniff, block is not a stricter setting, it is an unrecognised one.
- Adding it exposes any endpoint serving JavaScript with a non-JavaScript Content-Type, which usually means a static file handler with an incomplete media type map.
- It does nothing about a file that is genuinely served as text/html. If your upload endpoint returns user content with an HTML content type, nosniff is not the control that saves you.
Try it: HTTP Headers Checker
Check a live URL or paste headers you already have. It grades six security headers from A+ to F and lists every other header the response returned.
HTTP Headers Checker
LOCAL · Browser-OnlyView HTTP response headers for any URL
Enter any website URL to fetch and analyze its HTTP response headers. We'll automatically add https:// if needed.
Why Check Security Headers?
Security headers protect your website against common attacks like XSS, clickjacking, and MIME sniffing. They're set by your web server and cost nothing to implement. Missing security headers are one of the most common findings in security audits.
Related HTTP headers
All http headers →Content-Type: media type, charset and boundary
How Content-Type is structured, why the charset parameter still matters, what boundary does on a multipart upload, and how a wrong type breaks a page.
Content-Disposition: download prompts and file names
How to force a download instead of inline display, how filename and filename* differ, and how to send a non-ASCII file name that survives every browser.
Content-Security-Policy: directives, sources and reporting
How CSP directives are matched, what default-src actually falls back to, why unsafe-inline defeats the point of a policy, and how nonces and hashes work.
Cross-Origin-Resource-Policy: who may embed this response
How CORP lets a response refuse to be embedded by other sites, how same-site differs from same-origin, and why asset hosts have to send cross-origin.
X-Frame-Options: DENY, SAMEORIGIN and clickjacking
What DENY and SAMEORIGIN do, why ALLOW-FROM never worked, and how CSP frame-ancestors supersedes this header while it is still worth sending.
Referrer-Policy: controlling what the Referer header leaks
Every Referrer-Policy value compared, what modern browsers do when the header is missing, and why URLs with tokens in them leak to third parties without it.
Tools for this
- HTTP Headers Checker Free online HTTP headers checker - view HTTP response headers for any URL
- HTTP Request Builder Free online HTTP request builder - build and test HTTP requests with custom headers and body