X-Content-Type-Options and MIME Sniffing
Browsers sometimes second-guess the file type your server declares, inspecting the content and deciding for themselves what it really is. That helpful-sounding behaviour, called MIME sniffing, can turn an innocent-looking upload into executable code. One tiny header switches it off.
The short version
Send X-Content-Type-Options: nosniff on every response. It tells browsers to trust the Content-Type you declare instead of guessing, which prevents a whole class of attacks where a file is served as one type but executed as another. Check whether your site sends it with our headers check.
What MIME sniffing is
Every response your server sends carries a Content-Type header — the MIME type — that says what the body is: text/html, image/png, application/json and so on. Historically, some servers were misconfigured and sent the wrong type, so browsers added a fallback: if the declared type looked wrong, they would peek at the actual bytes and “sniff” the real type. If a file that claimed to be plain text actually started with <script>, the browser might decide it was HTML and render it.
Convenient for broken servers, dangerous for everyone. The browser is now overriding your intent based on attacker-controllable content.
Why that is dangerous
Consider a site that lets users upload files — an avatar, a document, an attachment. Suppose an attacker uploads a file that is served with a harmless Content-Type such as text/plain, but whose contents are actually valid HTML with an embedded script. Without protection, a browser that sniffs the content may decide the file is HTML, render it, and run the script in the context of your domain. That is a stored cross-site scripting attack delivered through your own file storage.
The same risk applies to any endpoint where the declared type and the real bytes can diverge — user uploads, generated downloads, or content served from a path an attacker can influence.
A second, quieter problem is confusion between resource types. If a browser is willing to run a response as a script even though it was labelled as something else, an attacker who can control part of a response body may be able to smuggle executable code past checks that only inspected the declared type. Sniffing widens the gap between what your server says a file is and what the browser is willing to treat it as, and every bit of that gap is somewhere an attacker can work.
The one-line fix
X-Content-Type-Options: nosniff
With nosniff in place, the browser stops guessing. It treats every response strictly as the Content-Type you declared. A file served as text/plain is shown as text, never executed as HTML. The header also makes browsers refuse to load scripts and stylesheets whose declared type does not match what was expected, closing a related path.
| Scenario | Without nosniff | With nosniff |
|---|---|---|
| Uploaded file typed as text but containing HTML | May render and run scripts | Served as inert text |
| Script served with a non-script MIME type | May still execute | Blocked from executing |
Setting it everywhere
Because the risk lives on individual responses, apply the header globally so nothing is missed. On Apache, Header always set X-Content-Type-Options "nosniff"; on Nginx, add_header X-Content-Type-Options "nosniff" always;. The value is always exactly nosniff — there are no other options to configure.
Where it fits
This is one of the cheapest, lowest-risk items on the security headers checklist: a fixed value with no downside for a correctly configured site. It pairs naturally with a strong Content Security Policy, which stops injected scripts from running even if one slips through. Once set, run a scan to confirm the header is present on your responses.
Frequently asked questions
Are there any values other than nosniff?
No. nosniff is the only meaningful value the header accepts. You either send it or you do not.
Could nosniff break anything on my site?
Only if your server is already sending wrong MIME types — for example labelling a JavaScript file as plain text. The correct fix is to send the right Content-Type, after which nosniff is entirely safe.
Do I need it if I already have CSP?
Yes, they cover different risks. CSP controls where scripts may come from; nosniff stops the browser from misinterpreting a file’s type in the first place. Use both.
Related guides
HTTP Security Headers: The Complete Checklist
Every important HTTP security header explained, what it protects against, and a copy-paste starting configuration.
Read →HTTP Security HeadersHSTS Explained: Strict-Transport-Security Done Right
How HSTS forces HTTPS, what the preload list means, and how to roll it out without locking yourself out.
Read →HTTP Security HeadersContent Security Policy (CSP) for Beginners
How CSP stops cross-site scripting, why it is hard to get right, and a safe way to deploy your first policy.
Read →Check your site against this guide
Run a free ScanOpsPro scan and see how your site handles the fundamentals.
Run a free scan