MIME type sniffing allows browsers to override the declared Content-Type of an HTTP response, which can be exploited by attackers to execute malicious content.

Why is this an issue?

MIME confusion attacks occur when an attacker successfully tricks a web browser into interpreting a resource as a different type than the one expected. When the Content-Type header is missing or incorrect, browsers try to deduce the correct content type by inspecting the resource content — a behavior known as MIME type sniffing. Attackers can exploit this when a website allows arbitrary file uploads: a malicious file containing JavaScript can be uploaded, and when a victim views it, the browser sniffs it as a script and executes it. Setting the X-Content-Type-Options response header to nosniff disables this behavior in all modern browsers.

In Express.js applications, when using the helmet library, the noSniff middleware controls this behavior and can be explicitly disabled.

What is the potential impact?

Cross-site scripting

If an attacker can upload a file to a publicly accessible location — such as a profile picture or document upload — they may embed JavaScript inside it, for example using a polyglot content file. When a victim views the file and the browser performs MIME sniffing, the malicious script executes in the victim’s browser context. This can allow the attacker to steal session cookies or credentials, or perform actions on behalf of the victim.

How to fix it

Code examples

The following code is vulnerable because the X-Content-Type-Options: nosniff response header is not set, allowing browsers to perform MIME type sniffing.

Noncompliant code example

const express = require('express');
const helmet = require('helmet');

let app = express();

app.use(
  helmet({
    noSniff: false, // Noncompliant
  })
);

Compliant solution

const express = require('express');
const helmet = require('helmet');

let app = express();

app.use(helmet.noSniff());

Resources

Documentation

Articles & blog posts

Standards