Skip to content

Helmet Security Middleware

Helmet is a small Express middleware that sets a collection of security-related HTTP headers with sensible defaults, closing off several common attack vectors with a single line of code.

What Does Helmet Actually Do?

Helmet doesn't add new functionality to your app, it sets a curated set of HTTP response headers that instruct browsers to enforce additional security restrictions: preventing your site from being embedded in a hostile iframe, restricting which sources scripts can load from, forcing HTTPS, and more.

Each protection Helmet provides corresponds to a specific, well-documented header, and you can enable, disable, or customize any of them individually if the defaults don't fit your app.

import express from 'express';
import helmet from 'helmet';

const app = express();

app.use(helmet());

app.get('/', (req, res) => res.send('Secured by Helmet'));

helmet() with no options applies a reasonable set of secure defaults, appropriate for most APIs and server-rendered apps out of the box.

What Helmet Sets by Default

Content-Security-Policy
X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN
Strict-Transport-Security
Referrer-Policy
  • Content-Security-Policy restricts which sources scripts, styles, and other resources can load from.
  • X-Content-Type-Options: nosniff stops browsers from guessing ("sniffing") a response's content type.
  • X-Frame-Options helps prevent clickjacking by restricting whether your site can be embedded in an iframe.
  • Strict-Transport-Security (HSTS) tells browsers to always use HTTPS for your domain going forward.

Helmet Headers Cheatsheet

The key headers Helmet manages and what each one protects against.

Header Protects Against
Content-Security-Policy XSS and unwanted resource loading
X-Content-Type-Options MIME-type sniffing attacks
X-Frame-Options Clickjacking via hidden iframes
Strict-Transport-Security Downgrade attacks to plain HTTP
Referrer-Policy Leaking sensitive URL data via the Referer header

Customizing Helmet's Defaults

Default settings sometimes conflict with legitimate app needs, for example, a strict Content-Security-Policy might block a third-party analytics script you actually want to load. Helmet lets you override individual policies rather than disabling protection entirely.

app.use(helmet({
  contentSecurityPolicy: {
    directives: {
      defaultSrc: ["'self'"],
      scriptSrc: ["'self'", 'https://trusted-cdn.example.com'],
    },
  },
}));

Adjust individual directives rather than disabling contentSecurityPolicy altogether whenever possible, keeping as much protection in place as your app's real requirements allow.

Helmet Is One Layer, Not the Whole Strategy

Helmet closes off a specific, well-known set of header-based vulnerabilities. It doesn't validate input, hash passwords, or replace authentication, it's one layer among several (validation, parameterized queries, rate limiting, HTTPS) that together form a reasonably secure application.

Common Mistakes

  • Disabling Helmet's contentSecurityPolicy entirely instead of customizing specific directives.
  • Assuming Helmet alone makes an application "secure" without addressing input validation or authentication.
  • Not testing the app after adding Helmet, some legitimate third-party scripts/styles can be blocked by the default CSP.
  • Applying Helmet only to some routes instead of the entire app via app.use().

Key Takeaways

  • Helmet sets a curated collection of security-related HTTP headers with one line of middleware.
  • Each header addresses a specific, well-documented browser-level vulnerability.
  • Helmet's defaults can (and sometimes must) be customized to fit an app's real resource needs.
  • Helmet is one layer of defense, not a replacement for validation, auth, or safe database queries.

Pro Tip

Add helmet() to every new Express project on day one, before writing any routes. It costs one line, has sensible defaults, and retrofitting a strict Content-Security-Policy onto a large, already-built app is much more work than starting with it in place.