Prevent MIME Sniffing

ID

javascript.mime_sniffing

Severity

high

Resource

Misconfiguration

Language

JavaScript

Tags

CAPEC:209, CWE:693, NIST.SP.800-53, OWASP:2021:A5, PCI-DSS:6.5.1

Description

MIME sniffing is a process used by web browsers to determine the file type of content received from a server when the server does not specify the MIME type. This is done by examining the first few bytes of the file to guess its type, which can be useful for displaying content correctly but also poses significant security risks.

Rationale

MIME sniffing can lead to security vulnerabilities because browsers might misinterpret malicious files as safe content. Common attacks include:

  • Cross-Site Scripting (XSS): Malicious scripts can be injected into web pages, executing on users' browsers and potentially stealing sensitive data.

  • Content Injection: Unauthorized content can be inserted into web pages, which might be displayed as safe by the browser.

  • Drive-by Downloads: Users might unknowingly download malware if the browser misidentifies a harmful file as legitimate.

Historically, older versions of Internet Explorer were particularly vulnerable to MIME sniffing attacks due to their aggressive content sniffing behavior. However, modern browsers like Chrome, Firefox, and Edge have improved their handling of MIME types and are less likely to perform MIME sniffing unless necessary. They prioritize the Content-Type header over sniffing, reducing the risk of security breaches. But if some HTTP response does not set the Content-Type header, browsers may still perform MIME sniffing.

Remediation

Use the X-Content-Type-Options Header: nosniff response header to prevent browsers from overriding the specified MIME type with their own guess.

It is also recommended to ensure that all responses include an accurate Content-Type header corresponding to the actual response content.

The following code fixes the vulnerability by setting the X-Content-Type-Options header to nosniff. Alternatively, security packages like helmet can be used to set this header automatically (in the default configuration):

const express = require('express');

const app = express();

app.use((req, res, next) => {
  // FIXED
  res.set('X-Content-Type-Options', 'nosniff');
  next();
});

// Your routes and other configurations here

Or by using the helmet.xContentTypeOptions() middleware.

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

const app = express();
// FIXED - The default configuration sets the X-Content-Type-Options header
app.use(helmet());
// alternatively, use the standalone middleware
app.use(helmet.xContentTypeOptions());

// Your routes and other configurations here

Configuration

The rule has no configurable options.

References