> ## Documentation Index
> Fetch the complete documentation index at: https://docs.37audits.com/llms.txt
> Use this file to discover all available pages before exploring further.

# X-Content-Type-Options Auditor

> Checks that the X-Content-Type-Options header stops browsers from guessing content types

<Info>
  **Security Auditor** — checks that the `X-Content-Type-Options` response header is set to `nosniff`, so browsers trust the declared `Content-Type` instead of guessing it.
</Info>

<CardGroup cols={2}>
  <Card title="Protection" icon="shield-halved">
    Stops browsers from running an uploaded file or a mislabeled response as a script or a stylesheet.
  </Card>

  <Card title="Standards" icon="book">
    Follows the X-Content-Type-Options section of the WHATWG Fetch Standard.
  </Card>
</CardGroup>

When a response arrives with a missing or unexpected `Content-Type`, browsers may look at its bytes and guess what it is ("MIME sniffing"). An attacker who can upload a file that looks like HTML or JavaScript can use that guess to run code on your site. `X-Content-Type-Options: nosniff` turns the guessing off: scripts and stylesheets with the wrong type are blocked. This auditor reads that header from the audited URL.

## How it works

1. **Fetch** — sends a `HEAD` request (or `GET` when `HEAD` is not supported) to the audited URL as 37AuditsBot. A blocked request ends the audit with `590`; any other failure (timeout, DNS, TLS, non-2xx answer) ends it with `500`.
2. **Read** — collects every `X-Content-Type-Options` header line and joins them with commas, as browsers do.
3. **First value** — like browsers, looks only at the **first** comma-separated value and compares it with `nosniff` ignoring letter case. `nosniff, nosniff` passes; `none, nosniff` fails.
4. **Rules** — a missing or empty header (`400`) and a first value other than `nosniff` (`401`) fail.
5. **Aggregate** — when every rule passes the audit is `SUCCESS` (`200`).
6. **Specification pin** — every run emits `37A-XContentTypeOptionsAuditor-100` (`INFORMATION`), naming the [X-Content-Type-Options section of the WHATWG Fetch Living Standard](https://fetch.spec.whatwg.org/#x-content-type-options-header) as of 2026-10-15. It does not change the overall status.

## What it audits

Every row maps to one `checkRule*` method and one `CheckCode`, in the order the auditor runs them. CheckCode suffixes use status ranges: `100` information, `200` success, `300–399` warning, `400–499` fail, `500–599` error.

| CheckCode | Status | When it fires | Recommendation | Why it matters |
| - | - | - | - | - |
| <a id="37A-XContentTypeOptionsAuditor-100" />`37A-XContentTypeOptionsAuditor-100` | `INFORMATION` | Always. Records the specification version this auditor implements. | — (recommendation is `null`; nothing for the site to change) | — |
| <a id="37A-XContentTypeOptionsAuditor-400" />`37A-XContentTypeOptionsAuditor-400` | `FAIL` | The page sends no `X-Content-Type-Options` header, or an empty one. | Add "X-Content-Type-Options: nosniff" to the responses of `{url}`. | Without this header, browsers may guess a file's type and run an uploaded file as a script, opening the door to cross-site scripting attacks. |
| <a id="37A-XContentTypeOptionsAuditor-401" />`37A-XContentTypeOptionsAuditor-401` | `FAIL` | The header is present but its first value is not `nosniff`. | Replace "`{value}`" with "nosniff" in the X-Content-Type-Options header of `{url}`. | Browsers ignore any value other than nosniff, so the site is as exposed to content-type guessing attacks as if the header were missing. |
| <a id="37A-XContentTypeOptionsAuditor-200" />`37A-XContentTypeOptionsAuditor-200` | `SUCCESS` | All rules passed. Message is `X-Content-Type-Options on {url} is "{value}", so browsers do not guess content types.` | — | — |
| <a id="37A-XContentTypeOptionsAuditor-500" />`37A-XContentTypeOptionsAuditor-500` | `ERROR` | The page could not be fetched (timeout, DNS, TLS, or a non-2xx answer other than a block). | Make sure `{url}` answers with HTTP 2xx, then run the audit again. Last error: `{error}`. | — |
| <a id="37A-XContentTypeOptionsAuditor-590" />`37A-XContentTypeOptionsAuditor-590` | `ERROR` | The audited page answered HTTP 403, HTTP 429 or a Cloudflare challenge, so 37AuditsBot was blocked before it could read the page. | Allow 37AuditsBot in your firewall or bot protection: allowlist its user agent, or verify its Web Bot Auth signature. See [https://www.37audits.com/bot](https://www.37audits.com/bot). | While 37AuditsBot is blocked this audit cannot look at the site, so problems on it go unreported. |

## Output documentation

| Status | Description | Test logic |
| - | - | - |
| **SUCCESS** | Browsers will not guess content types on this page | First header value is `nosniff`, any letter case (`200`). |
| **FAIL** | Browsers may guess content types on this page | Missing or empty header (`400`); first value is not `nosniff` (`401`). |
| **ERROR** | The auditor could not read the page | Fetch failure or non-2xx answer (`500`); site blocked 37AuditsBot (`590`). |
| **INFORMATION** | Specification pin | Always emitted (`100`); does not change overall status. |

## Risks and considerations

### Why MIME sniffing is dangerous

* Sites that serve user uploads (avatars, attachments, documents) are the classic target: a file uploaded as an image but containing HTML or JavaScript can be run by a browser that sniffs it, giving the attacker cross-site scripting on your domain.
* With `nosniff`, browsers block scripts and stylesheets whose `Content-Type` is not a script or CSS type, and Chrome's cross-origin read blocking protects more responses.

### Only `nosniff` counts

* The header has one valid value. Browsers read the first comma-separated value only, so a typo such as `no-sniff` or a stray value placed first leaves the protection off without any error.

### Setting it safely

* Add the header to every response (pages, APIs and static files), usually once in the web server, CDN or framework configuration.
* Make sure each response sends a correct `Content-Type`: with `nosniff`, a script served as `text/plain` stops loading.

### What this auditor does not check

* Only the audited URL is fetched; uploads, static assets and API responses may be served without the header.
* The `Content-Type` of the response is not checked.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.