X-Content-Type-Options is set
Why it matters
Browsers with MIME sniffing enabled attempt to guess a file's content type by reading its bytes, ignoring the Content-Type header. Attackers exploit this to serve malicious payloads in files uploaded or hosted as innocuous types — a file labeled text/plain containing JavaScript can be executed as a script. This crosses directly into CWE-79 (XSS) territory and OWASP A03 (Injection). The X-Content-Type-Options: nosniff header is a single-line fix that disables this guessing. It costs nothing to send and eliminates an entire class of content-type confusion attacks on every browser that honors it, which is all major browsers.
Severity rationale
Low because MIME sniffing attacks require an attacker-controlled upload or hosting vector, making exploitation dependent on other weaknesses being present first.
Remediation
Add the X-Content-Type-Options: nosniff header to all responses. This is a single directive with no configuration options:
# nginx
add_header X-Content-Type-Options "nosniff" always;
In Next.js next.config.js:
{ key: 'X-Content-Type-Options', value: 'nosniff' }
Most CDNs (Vercel, Cloudflare) also expose this as a toggle in their security settings dashboard. Confirm with curl -sI https://yoursite.com | grep -i x-content-type.
Detection
-
ID:
x-content-type-options -
Severity:
low -
What to look for: Count the occurrences of
X-Content-Type-Optionsin the response headers. At least 1 response must include this header. Extract the header value and verify it is exactly the stringnosniff(case-insensitive). -
Detector snippet (shell-capable tools only): If
curlis available, fetch HEAD against$BASE_URLand inspect the response headers forX-Content-Type-Options. If present with valuenosniff, pass. If missing, fail. Exit >=2 / command not found — fall back to prose reasoning.curl -sS -I $BASE_URL/ -
Pass criteria: Exactly 1
X-Content-Type-Optionsheader is present in the response and its value isnosniff. The value must not contain extra directives or trailing characters beyondnosniff. -
Fail criteria: Header is missing from the response, or the value is set to something other than
nosniff. -
Skip (N/A) when: The response is a redirect (3xx status) rather than a final document response, since headers on intermediate redirects are not delivered to the browser.
-
Detail on fail:
"No X-Content-Type-Options header — browsers may MIME-sniff responses" -
Remediation: This header prevents browsers from guessing (MIME-sniffing) the content type, which can lead to XSS attacks. It requires only a single header:
X-Content-Type-Options: nosniffIn nginx:
add_header X-Content-Type-Options "nosniff" always;. In Next.jsnext.config.js, add it to theheaders()array. Most CDNs (Vercel, Cloudflare) also provide this as a toggle in their dashboard.
External references
- cwe · CWE-79 — Improper Neutralization of Input During Web Page Generation (XSS)
- owasp:2021 · A03 — Injection
Taxons
History
- 2026-04-18·v1.0.0·Initial import from site-health-check·automated
- 2026-04-20·v1.1.0·Add Phase 6.0 detect-curl snippet for X-Content-Type-Options probe·by cakleinman