Skip to main content

X-Content-Type-Options.

Security Headers & TLS Config

Stops browsers from guessing file types — prevents MIME-sniffing attacks

What does this check test?

The `X-Content-Type-Options` header with the value `nosniff` instructs browsers to strictly follow the `Content-Type` header and never attempt to infer the MIME type of a response by examining its content. Without this header, browsers may 'sniff' the content and interpret a file differently than intended — for example, treating a plain text file as executable JavaScript if it contains script-like content.

Why does it matter?

MIME-sniffing attacks exploit the gap between a file's declared content type and what the browser decides to treat it as. An attacker could upload a file with a `.txt` extension containing JavaScript, and if the server serves it with `Content-Type: text/plain` but without `X-Content-Type-Options: nosniff`, the browser might execute it as a script in certain contexts. This is a well-known attack vector in user file upload scenarios and can lead to stored XSS.

Who is affected?

This header is essential for any site that serves user-uploaded content, API responses, or mixed content types. Applications with file upload features (profile images, document attachments, etc.) are especially vulnerable without it. Since the header has zero negative side effects and is trivial to deploy, every web application should include it regardless of whether it handles user uploads.

Where does this apply?

Set `X-Content-Type-Options: nosniff` on all HTTP responses, not just HTML pages. It is especially important on responses serving JavaScript, CSS, and user-uploaded files. Configure it at the server level (Nginx, Apache), CDN, or application middleware so it applies globally.

How to fix it

Nginx

nginx
add_header X-Content-Type-Options "nosniff" always;

Apache

apache
Header always set X-Content-Type-Options "nosniff"

Node.js / Express

js
app.use(helmet.noSniff());

Django — this is enabled by default via `SecurityMiddleware`. Ensure it is not disabled

python
SECURE_CONTENT_TYPE_NOSNIFF = True  # default is True

Flask

python
@app.after_request
def set_headers(response):
    response.headers['X-Content-Type-Options'] = 'nosniff'
    return response

Next.js

js
module.exports = {
  async headers() {
    return [{
      source: '/(.*)',
      headers: [{ key: 'X-Content-Type-Options', value: 'nosniff' }]
    }];
  }
};

Spring Boot — enabled by default. Verify in your security config

java
http.headers().contentTypeOptions(); // enabled by default
This is a single-value header (`nosniff` is the only valid value), so there is no configuration to tune. Just enable it globally. Verify with: `curl -sI https://yoursite.com | grep -i x-content-type`.

References

AppVet checks X-Content-Type-Options automatically

Run a free security scan and get a full report with actionable fixes, including a Fix with AI prompt you can paste into any coding tool.

Run Audit