Defaults.Exposed › Fixes › MIME-sniffing protection (X-Content-Type-Options)
How to fix MIME-sniffing protection (X-Content-Type-Options)
A one-line header that stops browsers from guessing what a file really is. Without it, a file someone uploads to your site — or a file on your own pages — can be mis-read by the browser and run as code, which is exactly how some attacks turn a harmless-looking upload into a way to steal your customers' sessions.
Bottom line for your business: Missing this header is a clear, scannable sign that the basics aren't in place. On its own it rarely takes a site down, but combined with a file-upload form or user-generated content it opens a path for an attacker to run malicious code in your visitors' browsers — hijacking logged-in sessions, stealing card-entry or login details, and putting you on the wrong side of a data-breach conversation. It is one of the cheapest fixes in security: one line, free, about five minutes.
What this can cost you
- Any page where customers or staff can upload files (avatars, documents, support attachments, listing photos) becomes a possible launch-pad for browser-side attacks.
- An attacker can disguise malicious code as an image or text file and have the visitor's browser run it — stealing their logged-in session on your site.
- Security questionnaires, cyber-insurance checks and enterprise buyers scan for this header; its absence reads as 'they don't do the basics' and can stall or sink a deal.
- Older browsers and some integrations 'sniff' content types and can mis-handle files in ways that break trust or leak data.
Why it matters. Browsers, when a server is vague about what a file is, will try to guess ("sniff") the content type. Attackers exploit that guess: upload a file the server labels as an image, but craft its contents so the browser decides it is actually JavaScript — and runs it. The X-Content-Type-Options: nosniff header tells every browser to stop guessing and trust the server's stated type, closing that whole class of trick. It is a scored check worth 25 points and is graded medium severity when missing.
The short version for the owner
There’s a quiet assumption built into every web browser: when it downloads a file from your site, it tries to work out what kind of file it is. Usually it trusts your server. But if your server is vague, the browser will guess — and that guessing is called MIME-sniffing.
The problem is that attackers can game the guess. They can craft a file that your server honestly believes is a harmless image, but that the browser, left to guess, decides is actually a piece of program code — and then runs it, right inside your customer’s browser, on your domain.
There is a one-line instruction that switches the guessing off: X-Content-Type-Options: nosniff. It tells every browser, “don’t guess — trust exactly what my server tells you.” That’s the whole fix. It’s free, it takes about five minutes, and on a properly built site it breaks nothing.
This check looks for that header. If it’s missing, you lose 25 points and it’s graded a medium-severity issue — not because the header alone is a catastrophe, but because its absence is a reliable sign that the basics haven’t been locked down.
What this can cost you
These are realistic, business-level scenarios — not worst-case theatre.
-
The “harmless attachment” that wasn’t. You run a support portal or a marketplace where customers upload files — receipts, photos, documents. An attacker uploads a file that your system stores and serves as an image. Without nosniff, a victim’s browser guesses the file is actually script and runs it — quietly stealing that visitor’s logged-in session on your site. Now the attacker is them: placing orders, reading messages, changing details. You find out when customers start complaining about activity they didn’t do.
-
The deal that stalls on a security questionnaire. A larger customer’s procurement team runs an automated scan of your site before signing. Missing security headers show up instantly. Even if nothing was ever exploited, the report says “basic web-security headers absent,” and suddenly you’re answering remediation questions and pushing your close date out by weeks — over a fix that would have taken five minutes.
-
The cyber-insurance renewal that gets harder. More insurers now run external scans before quoting or renewing. A clean header profile is cheap evidence of hygiene; a missing one is a small black mark that, stacked with others, nudges your premium up or your terms down.
-
The reputation hit you can’t easily undo. If a session-hijacking incident traces back to a file served from your domain, the story isn’t “an obscure header was missing” — it’s “[your business] leaked customer accounts.” That’s the version customers remember, and it costs far more than the fix ever would.
None of these require a sophisticated attacker. MIME-sniffing abuse is well-understood and automated, which is exactly why scanners flag the missing header so firmly.
What it actually is
When a browser receives a file, the server is supposed to label it with a content type (for example, image/png for a PNG image or text/html for a web page). Historically, browsers didn’t fully trust that label — partly because some servers got it wrong — so they’d peek at the file’s actual bytes and decide for themselves. That peeking is MIME-sniffing.
It was a convenience that became a liability. If an attacker can get a file onto your site (through an upload form, a comments field, an imported document) and influence its contents, they can craft something the server labels innocuously but the browser sniffs as executable script. The browser then runs it on your domain, with all the trust your domain carries.
X-Content-Type-Options: nosniff removes the guesswork entirely. With it set, the browser is told: use the server’s declared type and nothing else. A file labelled as an image is treated as an image, full stop — even if its contents look like script. The attack vector closes.
What “good” looks like: every response from your site — pages and assets alike — carries exactly this header:
X-Content-Type-Options: nosniff
There is no other valid value and nothing to tune. If your CDN and your server both add it (so you see nosniff, nosniff), that’s fine and still counts as a pass.
How to fix it (free, ~5 minutes)
Hand this section to whoever runs your website — your IT person, your web developer, or your hosting support. The fix is free and quick; there is nothing to buy. What you’re asking for is simple: “Add the response header X-Content-Type-Options: nosniff to every page and asset on the site.”
Here’s the detail for them, by common platform.
Cloudflare (or a similar CDN/proxy) — often the fastest place to do it, covering the whole site at once:
- Use a Response Header Transform Rule (Rules → Transform Rules → Modify Response Header) to set
X-Content-Type-Optionstonosnifffor all incoming requests. This applies it site-wide without touching the origin server.
Nginx — add inside the relevant server (or location) block:
add_header X-Content-Type-Options "nosniff" always;
The always keyword ensures it’s sent on error responses too. Reload Nginx after saving.
Apache — requires mod_headers enabled; in the site config or .htaccess:
Header always set X-Content-Type-Options "nosniff"
IIS / Windows hosting — in web.config under <system.webServer>:
<httpProtocol>
<customHeaders>
<add name="X-Content-Type-Options" value="nosniff" />
</customHeaders>
</httpProtocol>
Node / Express — set it for every response:
app.use((req, res, next) => {
res.setHeader('X-Content-Type-Options', 'nosniff');
next();
});
(Or use the helmet package, which sets this and several other security headers by default.)
Google Workspace / Microsoft 365 sites: these manage your email and documents, not your public website hosting, so the header isn’t set there — it’s set wherever your website itself is served (your CDN, web server, or site builder). If you use a hosted site builder (Squarespace, Wix, Shopify and similar), many add this header for you automatically; check the result rather than assuming, and ask their support if it’s missing.
After deploying, verify it. Re-run your scan, or have your developer check the response headers in browser developer tools (Network tab → click any request → Response Headers) and confirm X-Content-Type-Options: nosniff is present. Test the site briefly to confirm nothing styled or scripted broke — on a correctly-built site, nothing will.
Common mistakes
- Setting it on the homepage only. The header must be on every response — including images, scripts, stylesheets and uploaded files — because those are the resources sniffing affects. Apply it at the server or CDN level so it’s universal, not page-by-page.
- A typo in the value. The only valid value is
nosniff. Anything else (a blank value, a misspelling) fails the check and provides no protection. The scanner will report the value it actually saw so you can spot a typo. - Assuming it replaces a Content Security Policy. nosniff is one layer. It does not control which scripts are allowed to run — that’s CSP’s job. Add nosniff now as a quick win, and treat a proper CSP as the larger follow-up.
- Removing the “duplicate.” If both your CDN and origin set it, you’ll see it twice. That’s harmless — don’t spend time stripping one out.
- Paying for it. It’s a free configuration change. Monitoring, audits and portfolio dashboards are legitimately paid; adding a single header is not.
Hand this to your IT person
The technical summary: this check inspects the HTTP response headers and passes when X-Content-Type-Options is present and its (case-insensitive) value contains nosniff — including the multi-source nosniff, nosniff case where a CDN and origin both set it. Missing or any non-nosniff value fails. It’s a scored P2 check worth 25 points, graded medium severity when failing, and maps to OWASP Top 10 A05 (Security Misconfiguration). The remediation is a single static response header applied across all responses; there are no parameters and no valid alternative values. Set it at the edge (CDN) for whole-site coverage, or at the web server with always semantics so it’s emitted on error responses too, then confirm in the response headers.
FAQ
We don't let anyone upload files. Do we still need this?
Yes, and it's still worth doing. The header is defence-in-depth: it also stops the browser mis-reading scripts, stylesheets and data files served from your own site, which protects against several cross-site-scripting tricks even on sites with no upload form. It costs nothing and never breaks a correctly-configured site, so there's no reason to skip it.
Will adding this break anything on our website?
Almost never. nosniff simply makes browsers honour the content type your server already sends. The only way it causes trouble is if your server is mislabelling files — for example sending a stylesheet or script with the wrong type. If something does break, that's a real bug nosniff exposed rather than caused, and it's worth fixing anyway. Test once after deploying.
What does 'good' actually look like?
A single response header on every page and asset: X-Content-Type-Options: nosniff. That's the entire correct configuration — there are no other valid values and no tuning to do.
Our CDN (Cloudflare or similar) and our server both add it — is that a problem?
No. Seeing the value twice ("nosniff, nosniff") because both the CDN and the origin set it is completely fine and still passes. You don't need to remove one.
Does fixing this cost money?
No. The fix is one line of free configuration on your web server or CDN. Anyone charging you to add a single header is overcharging. The only things worth paying for in this area are ongoing monitoring, a portfolio view across many sites, or a formal audit — not the fix itself.
How is this different from a Content Security Policy (CSP)?
They're complementary. CSP controls which scripts and resources are allowed to load at all; nosniff stops the browser from mis-classifying a file it does load. You want both. nosniff is far simpler and faster to add, so it's a good first step on the way to a full CSP.