Don't Sniff Mimetype Middleware
This package provides a small, focused Express/Connect middleware designed to set the `X-Content-Type-Options` HTTP header to `nosniff`. This header is a crucial client-side security measure that prevents browsers from "sniffing" or inferring the MIME type of a response, thereby enforcing the `Content-Type` header explicitly sent by the server. Without it, browsers might execute files (like HTML or JavaScript) that are incorrectly served with a generic MIME type (e.g., `text/plain`), leading to cross-site scripting (XSS) or other content-based attacks. The current stable version is 1.1.0, which was last published in 2019, indicating a highly mature and stable, but infrequently updated, codebase. It is a standalone component of the broader Helmet.js suite, which includes this functionality by default. Its key differentiator is offering granular control over this specific security header without deploying the entire Helmet.js bundle.
Common errors
-
TypeError: dontSniffMimetype is not a function
cause The `dont-sniff-mimetype` module exports a function that must be called to produce the middleware. It's not the middleware itself.fixCall the imported function when using it as middleware: `app.use(dontSniffMimetype());` -
Refused to execute script from '<URL>' because its MIME type ('<incorrect-type>') is not executable, and strict MIME type checking is enabled.cause This error indicates `dont-sniff-mimetype` is working as intended. The browser received a resource with `X-Content-Type-Options: nosniff` and an `Content-Type` header (e.g., `text/plain`) that doesn't permit execution (e.g., for JavaScript).fixVerify that your server is sending the correct `Content-Type` header for all resources. For example, JavaScript files should be `application/javascript`, not `text/plain`. If the resource truly isn't meant to be executable, no fix is needed; the package is preventing a potential vulnerability. -
Server responses do not include 'X-Content-Type-Options: nosniff' header.
cause The middleware was not correctly applied to the Express/Connect application, or it was overridden by subsequent middleware.fixEnsure `app.use(dontSniffMimetype());` is called early in your middleware chain, before any routes that might send responses without this header. Inspect network requests in developer tools to confirm the header is present.
Warnings
- gotcha If you are already using the full `helmet` package (e.g., `app.use(helmet())`), this `dont-sniff-mimetype` middleware is redundant. Helmet includes `X-Content-Type-Options: nosniff` by default.
- gotcha This package is very old, with its last update occurring in 2019. While the underlying security header remains relevant, the package itself receives minimal to no active maintenance.
- gotcha While the `X-Content-Type-Options: nosniff` header is widely supported by modern browsers (Chrome, Edge, Firefox 50+, IE 8+, Safari 11+), older or less common browsers might not fully respect it, potentially still attempting MIME sniffing.
Install
-
npm install dont-sniff-mimetype -
yarn add dont-sniff-mimetype -
pnpm add dont-sniff-mimetype
Imports
- dontSniffMimetype
import dontSniffMimetype from 'dont-sniff-mimetype';
const dontSniffMimetype = require('dont-sniff-mimetype'); - middleware function
app.use(dontSniffMimetype);
app.use(dontSniffMimetype());
Quickstart
import express from 'express';
import dontSniffMimetype from 'dont-sniff-mimetype';
const app = express();
// Apply the X-Content-Type-Options: nosniff header to all responses
app.use(dontSniffMimetype());
app.get('/', (req, res) => {
res.set('Content-Type', 'text/html');
res.send('<h1>Hello! MIME sniffing is prevented.</h1><script>console.log("This script runs because it's HTML, but if a JS file was served as text/plain, it would be blocked.");</script>');
});
app.get('/untrusted.txt', (req, res) => {
// Serve a 'text' file that looks like JavaScript, but is explicitly text/plain
// With 'nosniff', browsers will not execute this as script.
res.set('Content-Type', 'text/plain');
res.send('alert("This should not execute as JavaScript!"); console.log("MIME sniffed prevented for untrusted.txt");');
});
app.listen(3000, () => {
console.log('Server running on http://localhost:3000');
console.log('Visit / to see HTML. Visit /untrusted.txt and check headers/console.');
});