squirrelscan
GitHub

X-Content-Type-Options: nosniff and why it matters

Without nosniff a browser may execute an uploaded file as script because the bytes look like one. squirrel reads the header once per site.

What X-Content-Type-Options is

X-Content-Type-Options: nosniff tells the browser to trust the Content-Type you sent and never guess a different type from the bytes. MIME sniffing exists because early servers were unreliable about content types, and it is still on by default.

Sniffing turns a mislabelled upload into a script. A file served as text/plain that happens to start like JavaScript can be loaded in a <script> tag and executed under your origin. nosniff also makes the browser refuse a stylesheet or script whose declared type is wrong, which surfaces server misconfiguration instead of hiding it. The header has one valid value and no compatibility cost.

What squirrel checks

The rule reads the response headers of the first crawled page and emits a single check named x-content-type:

  • Skipped when the crawl produced no pages. Message: No pages to check.
  • Pass when the header value, lowercased, is exactly nosniff. Message: X-Content-Type-Options: nosniff is set.
  • Warn when the header is present with any other value. Message: X-Content-Type-Options has unexpected value, with the value found and nosniff as expected.
  • Info when the header is absent. Message: Missing X-Content-Type-Options header, with Add: X-Content-Type-Options: nosniff as the value.

Severity is info and the weight is 3, so a missing header nudges the Security score rather than dominating it.

How to fix it

X-Content-Type-Options: nosniff

Set it on every response, not only on HTML. The header matters most on the paths that serve user uploads and generated files, and it is easiest to add once at the edge or in a global middleware.

The one thing to check after enabling it is that scripts and stylesheets go out with correct types. nosniff makes the browser reject a script served as text/html, which is a real bug it was previously hiding.

Rule IDsecurity/x-content-type
CategorySecurity
ScopeSite-wide
Severityinfo
Weight3/10

Enable / disable

Disable this rule

[rules]
disable = ["security/x-content-type"]

Disable all Security rules

[rules]
disable = ["security/*"]

Enable only this rule

[rules]
enable = ["security/x-content-type"]

enable replaces the default ["*"], so this is the only rule selected. Leave disable out: a rule that matches any disable pattern is skipped even when enable names it. Only an enabled setting under a rule’s own [rule_options] table overrides both lists.

Security findings ship in every audit next to the SEO, performance and agent experience rules. See Website security scan with AI for how an agent works through a report.

References

Check your site

Run squirrel audit https://example.com and open the Security section of the report. The header is reported once for the site with the exact value your server sent. Signed-out local audits need no account and cost nothing. Signed-in audits spend credits.

Type to search…

↑↓ navigate↵ openesc close