MIME Types and Browser Security

Browsers enforce MIME types as part of their security model. MIME sniffing risks, X-Content-Type-Options: nosniff, CSP script-src, and cross-origin font CORS rules.

MIME Types and Browser Security: Sniffing, nosniff, CSP, and CORS

Browsers enforce MIME types as part of their security model. Content-Type headers are not just metadata about file format; they control how browsers parse, execute, and sandbox content. When a server sends the wrong MIME type, browsers make security-relevant decisions about whether to execute scripts, render markup, or apply cross-origin restrictions. MIME sniffing, where the browser detects the actual content type from the file's bytes rather than the declared header, was introduced to handle misconfigured servers but creates attack vectors.1 X-Content-Type-Options: nosniff closes this gap by instructing browsers to trust the declared type exactly.2 Strict CSP configurations check MIME type before executing scripts, adding a second enforcement layer beyond the URL allowlist. Cross-origin resources like fonts and images loaded by canvas require CORS headers that interact with MIME type expectations. Understanding these interactions is fundamental to hardening a web application against content-type confusion attacks.

Browser MIME enforcement mechanisms

  • MIME sniffing browser inspects response bytes to guess the real type when Content-Type is missing or generic
  • X-Content-Type-Options: nosniff tells the browser to trust the declared Content-Type exactly
  • Cross-origin fonts require Access-Control-Allow-Origin regardless of MIME type — failures are silent
  • Subresource Integrity checks a content hash after the MIME type check passes, not instead of it

Opens the MIME Type Reference with this page's checklist shown at the top of the tool.

Open in the tool →

What MIME sniffing is and when browsers activate it

MIME sniffing is the process by which a browser inspects the first bytes of a response body to determine the actual content type, overriding or supplementing the declared Content-Type header. The WHATWG MIME Sniffing Standard defines the exact sniffing algorithm.3 Browsers activate sniffing primarily when the server sends no Content-Type header, when the Content-Type is text/plain for a resource loaded in a context that expects a specific type, or when the browser detects executable content in a response declared as a safe type.

Content-type confusion attacks

The security risk is a content-type confusion attack: an attacker uploads a file that appears to be an image (and passes server-side format validation) but contains an HTML or script payload that the browser detects and executes when sniffing is active.4 Furthermore, older Internet Explorer versions were particularly aggressive sniffers, treating any response as HTML if the content began with HTML-like bytes.

X-Content-Type-Options: nosniff mechanics

The X-Content-Type-Options: nosniff response header instructs the browser to use the declared Content-Type value exactly and not perform sniffing. When nosniff is present, the browser refuses to execute a script served as text/plain, refuses to render a stylesheet served as application/octet-stream, and refuses to treat any response as HTML unless the Content-Type declares it as such. Modern browsers apply nosniff to all resource types; older browsers applied it only to scripts and stylesheets.5

Why nosniff requires correct MIME types first

Consequently, setting nosniff on every response is best practice rather than applying it selectively. Building on this, nosniff works correctly only when combined with accurate MIME types. Setting nosniff on a server that sends wrong types for images or scripts will cause browsers to reject those resources outright instead of attempting to sniff the correct format from the response body. Fix MIME types first, then enable nosniff globally so that the browser's strict trust in your declared types actually helps rather than hurts your users.

Cross-origin resource MIME rules for fonts and images

Browsers apply CORS enforcement to certain resource types loaded cross-origin. Fonts are the most important example: any font loaded from a different origin requires an Access-Control-Allow-Origin header from the font server, regardless of the MIME type.6 The failure is silent and there is no console error. For images, CORS enforcement applies specifically to canvas operations: drawing a cross-origin image onto a canvas taints it unless the image server sends Access-Control-Allow-Origin and the img element carries crossorigin="anonymous". MIME type plays a secondary role in this: an incorrectly typed cross-origin font still fails even if CORS is configured, because the browser must also recognise the MIME type as a font format. Furthermore, CSP's font-src directive controls from which origins fonts may be loaded, adding a third layer of restriction on top of CORS and MIME type validation.

Subresource Integrity and its relationship with MIME type enforcement

Subresource Integrity (SRI) adds a cryptographic hash check to external script and stylesheet elements. When an element carries an integrity attribute containing a base64-encoded hash, the browser downloads the resource, computes the hash against the received bytes, and compares it to the declared value before executing or applying the resource. A mismatch causes the browser to block the resource entirely. SRI requires CORS on the resource server: the response must include Access-Control-Allow-Origin for the browser to share the response body with the integrity checking algorithm.7

MIME type enforcement and SRI operate as independent checks applied in sequence. A script must carry a valid JavaScript MIME type and pass the integrity hash check before the browser executes it. Serving an SRI-protected script with text/plain fails the MIME type check first, and the browser blocks the resource before computing the hash at all. Consequently, fixing the MIME type is a prerequisite before SRI integrity errors become meaningful.

require-sri-for and layered script security

The CSP require-sri-for directive (available in some browsers) enforces that all scripts and styles in the document carry SRI integrity attributes, blocking any script or stylesheet that lacks a valid hash regardless of its origin or MIME type. Combining require-sri-for with a script-src allowlist and X-Content-Type-Options: nosniff creates three independent enforcement layers: only approved origins, only verified content hashes, and only correct MIME types. Implementing all three layers means an attacker must compromise the origin, match the expected hash, and serve the correct MIME type simultaneously, which raises the difficulty of a successful content injection attack dramatically.

Generating SRI hashes for your build pipeline

Generating SRI hashes during the build step ensures every deployed script and stylesheet carries an integrity attribute that matches the exact bytes the browser will receive. The openssl dgst command computes a SHA-384 hash of a file and the base64 utility encodes it for the integrity attribute value.7 Build tools like webpack-subresource-integrity automate this process by computing hashes at bundle time and injecting the integrity and crossorigin attributes into the generated HTML, removing the manual step entirely.8

Hashing at build time also means the integrity value stays in sync with the exact bytes the browser receives, so a minification change that alters the file automatically produces a new hash without manual intervention. This prevents the stale-hash problem where a code update ships new script bytes but an old integrity attribute blocks them. pair the script Content-Type with SRI so the MIME check and the hash check pass together.

When to use this

Use this guide when hardening a web application against content-type confusion attacks, auditing response headers for security posture, or diagnosing silent resource failures caused by CORS or MIME type mismatches.

Examples

Add X-Content-Type-Options: nosniff globally in Nginx

Place in the http {} block to apply to all responses. Combined with correct MIME types, this prevents content-type confusion attacks.

Verify nosniff and Content-Type with curl

Check both the Content-Type and X-Content-Type-Options headers together to confirm both are correct.

CSP script-src with MIME type enforcement

Strict CSP rejects scripts served with incorrect MIME types. Setting the correct type and CSP together prevents both sniffing and unlisted script execution.

Sources
  1. 1.

    Mozilla Developer Network, "MIME type verification," developer.mozilla.org, accessed June 2026. https://developer.mozilla.org/en-US/docs/Web/Security/Practical_implementation_guides/MIME_types

  2. 2.

    OWASP Foundation, "HTTP Headers Cheat Sheet," owasp.org, 2024. https://cheatsheetseries.owasp.org/cheatsheets/HTTP_Headers_Cheat_Sheet.html

  3. 3.

    Adam Barth and Ian Hickson, "Media Type Sniffing," draft-ietf-websec-mime-sniff-03, IETF, May 2011. https://datatracker.ietf.org/doc/html/draft-ietf-websec-mime-sniff-03

  4. 4.

    MITRE, "CAPEC-209: XSS Using MIME Type Mismatch," capec.mitre.org, accessed June 2026. https://capec.mitre.org/data/definitions/209.html

  5. 5.

    Mozilla Developer Network, "X-Content-Type-Options header," developer.mozilla.org, accessed June 2026. https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/X-Content-Type-Options

  6. 6.

    W3C, "CSS Fonts Module Level 3," w3.org, 2018. https://www.w3.org/TR/2018/REC-css-fonts-3-20180920/

  7. 7.

    W3C, "Subresource Integrity," w3.org, 2016. https://www.w3.org/TR/2016/REC-SRI-20160623/

  8. 8.

    "webpack-subresource-integrity," GitHub, github.com, accessed June 2026. https://github.com/waysact/webpack-subresource-integrity

FAQ

A content-type confusion attack exploits MIME sniffing by uploading a file that passes server-side validation as a safe format (such as an image) but contains HTML or script content that the browser detects and executes. Setting X-Content-Type-Options: nosniff prevents browsers from overriding the declared Content-Type, blocking this class of attack.

In modern browsers, yes. nosniff applies to scripts, stylesheets, images, fonts, and other resource types. Older browser implementations applied it only to scripts and stylesheets. Setting it on all responses is the safest approach, as it closes the sniffing gap across all resource types regardless of browser version.

Browsers enforce CORS for cross-origin font requests but report the failure silently rather than with a console error. The font request completes with a 200 status, but the browser discards the response because Access-Control-Allow-Origin is missing. Check the font request in the Network panel and look for a CORS policy error in the response details section.

Yes, indirectly. Browsers that enforce strict MIME checking for scripts check the Content-Type independently of CSP. A script with a valid CSP allowlist entry but an incorrect MIME type still fails to execute when X-Content-Type-Options: nosniff is present. CSP controls trusted origins; MIME type checking controls whether the response is safe to execute.

Not always. Sniffing was introduced to handle misconfigured servers that omit Content-Type headers, improving compatibility. The security risk arises specifically when sniffing overrides a declared type and causes the browser to execute content in an unexpected context. nosniff prevents this override while keeping sniffing for responses with no declared type. CapyToolkit's MIME reference documents which Content-Type values browsers expect for each format, helping you avoid the misconfigurations that make sniffing necessary in the first place.

Additional resources