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.

ScenarioWithout nosniffWith nosniff
Uploaded file typed as text but containing HTMLMay render and run scriptsServed as inert text
Script served with a non-script MIME typeMay still executeBlocked 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.

nosniff assumes your Content-Type headers are correct. Turning off sniffing means the browser fully trusts what you declare, so a genuinely mislabelled file may now fail to load. Before deploying, make sure your server sends accurate MIME types — the fix is to label content correctly, not to leave sniffing on as a crutch.

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

Check your site against this guide

Run a free ScanOpsPro scan and see how your site handles the fundamentals.

Run a free scan