1. Abstract
Prevent browser MIME sniffing for browser-loadable responses with X-Content-Type-Options: nosniff.
X-Content-Type-Options tells browsers to trust declared media types instead of sniffing content, reducing the risk that mislabeled files execute as active content.
2. Classification
- Check ID
- x-content-type-options
- Check version
- 1.0.0
- Package path
- lib/checks/x-content-type-options/versions/1.0.0
- Category
- Security & Trust
- Subcategory
- Security & Trust
- Check group
- Browser Trust
- Check group ID
- browser-trust
- Maturity
- Established
- Scope
- page
- Check weight
- 1
3. Input And Output Contracts
- Input
- [email protected]
- Output
- [email protected]
- Resources inspected
- X-Content-Type-Options, Content-Type, nosniff
4. Scoring Semantics
| Step ID | Title | Weight | Description |
|---|---|---|---|
applicability | Validate response applicability | 0.15 | Classify response status, body presence, browser-loadability, and whether the response is eligible for nosniff. |
header-presence | Find X-Content-Type-Options | 0.25 | Check for X-Content-Type-Options on the scanned browser-loadable response. |
value-syntax | Validate nosniff value | 0.25 | Parse split values, first effective value, case-insensitive nosniff, extra values, and malformed values. |
content-type | Review Content-Type | 0.2 | Validate Content-Type presence, parseability, and plausibility for the scanned response. |
observed-responses | Review observed browser responses | 0.15 | When Chrome response evidence is available, check sampled same-origin responses for nosniff and Content-Type. |
5. Package Documentation
X-Content-Type-Options Check v1.0.0
Status
- Version:
1.0.0 - Check identifier:
x-content-type-options - Input contract:
[email protected] - Output contract:
[email protected] - Scope: page
Abstract
This check validates X-Content-Type-Options: nosniff on the scanned browser-loadable response. It verifies header presence, parses the effective nosniff value using Fetch-compatible list behavior, reviews the response Content-Type, and, when Chrome response evidence is available, reviews sampled same-origin responses loaded during page render.
Observed Chrome responses are sampled evidence. The check does not claim complete site-wide coverage for routes Chrome did not request.
Motivation
Browsers historically sniffed response bytes when Content-Type was absent or incorrect. MIME sniffing can turn a low-privilege response, such as text or an upload, into executable HTML or script-like content.
X-Content-Type-Options: nosniff asks browsers to trust the declared media type instead of guessing. It is most useful when paired with accurate Content-Type headers.
Normative Model
The WHATWG Fetch Standard defines the X-Content-Type-Options response header and the nosniff value.
The only defined value is nosniff, matched case-insensitively. Fetch derives the effective value by getting, decoding, and splitting X-Content-Type-Options values. If the first split value is an ASCII case-insensitive match for nosniff, nosniff is active.
Fetch directly applies nosniff request blocking to script-like and style destinations:
- script-like responses are blocked when their MIME type is missing or not JavaScript
- stylesheet responses are blocked when their MIME type is missing or not
text/css
RFC 9110 defines Content-Type as the response header that identifies the representation media type. nosniff does not replace correct Content-Type.
Applicability
The check applies to the scanned browser-loadable HTTP(S) response and expects a renderable representation.
Response statuses that do not carry a renderable representation, such as 204 No Content, 205 Reset Content, 304 Not Modified, and redirects, fail this check when scanned as the primary page response.
When Chrome-observed response evidence is present, the check reviews sampled same-origin responses such as documents, scripts, stylesheets, fetch/XHR responses, images/SVG, fonts, text, JSON, and XML. Third-party responses are recorded only as context because the scanned site may not control them.
Pass Criteria
The check passes baseline validation when:
- the scanned response has a renderable body
X-Content-Type-Optionsis present- the first effective value is
nosniff - the header has no extra non-conformant values
Content-Typeis present and parseable- the observed
Content-Typeis plausible for the scanned response - sampled same-origin browser responses, when available, consistently emit conformant
nosniff
Warning Criteria
Warnings include:
- the first effective value is
nosniff, but extra values are present nosniffis present butContent-Typeis missingnosniffis present butContent-Typeis malformed- the scanned response looks like HTML but is not served as
text/htmlorapplication/xhtml+xml - sampled same-origin browser responses omit
nosniff - sampled same-origin browser responses use non-conformant
X-Content-Type-Optionsvalues - Chrome response evidence is unavailable, so route consistency cannot be sampled
Failure Criteria
Failures include:
- scanned response does not have a renderable body
- applicable browser-loadable response omits
X-Content-Type-Options - the first effective value is not
nosniff - the value is malformed, such as
none,off,nosniff=1,nosniff; mode=block, or another unsupported token
Absence on sampled subresources is warning-level in this version unless the scanned page response itself fails. This keeps the result tied to observed evidence without claiming every route has been crawled.
Evidence Model
The check emits step-level evidence for:
- final URL and status
- response content type
- body/renderability classification
- raw
X-Content-Type-Optionssummary - parsed split values
- first effective value
- whether
nosniffis active - whether the value is conformant
- extra values
- parsed
Content-Typemedia type - whether the media type is plausible for the scanned response
- observed Chrome response count
- same-origin observed response count
- eligible sampled response count
- missing or malformed
nosniffcounts in sampled responses - summarized affected sampled responses
Evidence must not include cookies, authorization headers, complete response header dumps, complete HTML, request credentials, uploaded file contents, or unrelated sensitive values.
Validation/Scoring Steps
applicability(0.15): classify response status, body presence, and eligibility.header-presence(0.25): check forX-Content-Type-Optionson the scanned response.value-syntax(0.25): parse split values, first effective value, case-insensitivenosniff, extra values, and malformed values.content-type(0.20): validateContent-Typepresence, parseability, and plausibility.observed-responses(0.15): when Chrome response evidence is available, review sampled same-origin responses fornosniffandContent-Typesignals.
Standard Behavior
If an eligible browser-loadable response lacks X-Content-Type-Options, the result fails.
If the header exists but the first effective value is not nosniff, the result fails.
If the first effective value is nosniff but extra values are present, the result warns because browser behavior may still activate while the header is non-conformant.
If nosniff is present but Content-Type is missing or implausible, the result warns.
If Chrome-observed same-origin responses are missing or misusing nosniff, the result warns and identifies sampled affected responses.
Non-Standard And Real-World Behavior
Security header scanners commonly expect X-Content-Type-Options: nosniff across browser-facing responses, even though Fetch's strict request-blocking algorithm directly targets script-like and style destinations.
Many sites emit nosniff globally from a web server, CDN, reverse proxy, or application middleware. That is generally safe when Content-Type is configured correctly. It can reveal misconfigured JavaScript or CSS resources because browsers may block them once nosniff is active.
Some legacy applications depend on MIME sniffing to compensate for incorrect media types. The correct remediation is to fix Content-Type, not to omit nosniff.
Non-Goals And Limitations
This check does not:
- prove every route on the site sends
nosniff - crawl upload, download, API, or authenticated routes unless Chrome requested them during render
- prove every resource has a correct media type
- execute browser-blocking assertions beyond observed response metadata
- replace CSP, HSTS, CORP, COEP, CORS, Referrer-Policy, or download-safety checks
- treat
nosniffas protection when the declaredContent-Typeis wrong - pass responses that cannot contain or render content when they are scanned as
the primary page response
References
Source: lib/checks/x-content-type-options/versions/1.0.0/docs.md
6. Version Changelog
x-content-type-options v1.0.0 Changelog
Initial release of the X-Content-Type-Options check.
This version evaluates:
X-Content-Type-Optionsheader presence- Fetch-compatible first-value
nosniffhandling - extra or malformed values
- scanned response
Content-Typepresence and plausibility - sampled same-origin Chrome-observed responses when browser response evidence is available
Source: lib/checks/x-content-type-options/versions/1.0.0/changelog.md