Security Headers

HTTP security headers are response headers that tell the browser how to behave defensively — what content to load, whether to allow framing, and when to force HTTPS. They're one of the highest-leverage hardening steps available: a few lines of configuration that mitigate whole classes of attacks.

They're a backstop, not a substitute for fixing root causes, but a strong header set turns many would-be exploits into non-events.

TL;DR

Quick Example

In Express, Helmet sets a strong baseline of headers in one line:

Then tighten individual policies (especially CSP) for your app's needs.

Core Concepts

The essential headers

Content-Security-Policy (CSP)

The most powerful and most complex header. It allowlists where scripts, styles, images, and connections may come from, and can block inline scripts — the main XSS vector. Start permissive in report-only mode, watch violations, then tighten. See XSS.

HSTS

Strict-Transport-Security makes the browser remember to use HTTPS, preventing downgrade attacks. Pair it with a strong TLS setup — see HTTPS & TLS.

Best Practices

Configure Helmet explicitly

Or set them at the edge (Nginx)

Roll CSP out safely

Common Mistakes

Allowing inline scripts in CSP

Enforcing a brand-new CSP straight away

A strict CSP almost always breaks something on first deploy. Ship it reportOnly first, fix the violations, then enforce.

Setting headers on some responses only

Apply headers globally (middleware or edge), not per-route — gaps are exactly where attacks land. Note X-XSS-Protection is deprecated; rely on CSP instead.

Testing

Scan your live site to confirm coverage:

FAQ

Which security headers are most important?

Content-Security-Policy and Strict-Transport-Security deliver the most protection (XSS and transport downgrade). After those, add X-Content-Type-Options: nosniff, clickjacking protection (frame-ancestors/X-Frame-Options), and a Referrer-Policy.

Should I use X-Frame-Options or CSP frame-ancestors?

Prefer CSP frame-ancestors — it's the modern, more flexible replacement. Keep X-Frame-Options: DENY alongside it for older browsers that don't support CSP framing directives.

Why is my CSP breaking the site?

Usually because real scripts, styles, or API calls aren't in the allowlist, or the app relies on inline scripts. Run in report-only mode, read the violation reports, and add the legitimate sources (or refactor inline scripts to use nonces).

Is Helmet enough on its own?

Helmet gives a solid baseline, but the default CSP is intentionally generic. Tailor the CSP directives to your actual asset and API origins to get real protection.

Related Topics

References