X-Content-Type-Options: nosniff tells the browser to trust the Content-Type you send and not guess from the content. It also blocks script and stylesheet loads whose MIME type does not match. It stops uploaded text or images from being run as HTML or JavaScript.
Two effects, one header
MDN describes the directive as having two effects depending on context.
- Request blocking. For a request whose destination is a script or a style, the browser blocks the response if the MIME type is wrong: a JavaScript MIME type for scripts,
text/cssfor stylesheets. - No MIME sniffing. For other responses, including navigations to a new document, the browser uses the declared Content-Type as is. If the server sends
text/plainwithnosniff, the browser will not render the body as HTML even when it contains HTML markup.
Without the header, a browser may inspect content to infer its type. That is the root of MIME confusion attacks.
Why uploads are the main risk
Suppose your app lets users upload a file and later serves it back from your origin. If an attacker uploads a file containing script and the browser sniffs it as HTML, the script runs with your origin's privileges. MDN notes that nosniff prevents this kind of XSS where user uploaded content is executed as an HTML document, even if it was served as plain text or another type.
The header is a safety net, not the control. Serve user content with a correct and specific Content-Type, from a separate domain where possible, and validate what you accept.
What can break
The request blocking behaviour is the one that surprises teams. After you add the header, a script served as text/plain or text/html by a misconfigured static server, or a CSS file with a generic type, will stop loading. Typical causes are a missing type mapping for a new file extension and an error page served in place of a script with a 200 status.
| Symptom | Likely cause | Fix |
|---|---|---|
| Script blocked after adding header | Wrong or missing Content-Type | Correct the type mapping |
| Stylesheet not applied | Served as text/plain or HTML | Serve as text/css |
| Download renders as a page | Type absent and sniffing now off | Send explicit type or Content-Disposition |
How to test it
curl -sI https://example.com/app.js | grep -i -E "content-type|x-content-type-options"
You should see a JavaScript type and nosniff. Repeat for one stylesheet, one image and one user uploaded file. Then open the browser console on a staging build: blocked loads are reported there with the reason.
Try it yourself
Click through the web app scan to see how header findings are reported and grouped, then compare with your own curl output.
Click through it at your own pace, or open it full screen.
Quick check
Does nosniff replace a Content Security Policy?
No. It controls type handling. A CSP controls what scripts and other resources the page may load or run. Use both.
Is there a value other than nosniff?
MDN documents a single directive, nosniff, so that is the value to send.
Will it fix a wrong Content-Type for me?
No. It makes a wrong type fail loudly. You still have to send the right one.
Safeguard focuses on dependency scanning, SBOMs and policy gates for the code you ship; run a free scan at gold.safeguard.sh/scan.
Sources
Last reviewed: 19 October 2026.