When developing web applications, security should always be a top priority. A simple yet powerful way to protect your app and users is by configuring HTTP security headers. These headers instruct the browser on how to behave when handling content from your site, helping to mitigate common attacks like cross-site scripting (XSS), clickjacking, and content sniffing.
In this article, we’ll walk through an Express.js middleware that sets key HTTP headers, explain their purposes, and suggest additional headers you should consider for modern, robust protection.
An example of security header middleware
The following is an example of security header middleware:
const express = require('express');
const app = express();
app.use((req, res, next) => {
res.set({
'Strict-Transport-Security': 'max-age=63072000; preload',
'X-Content-Type-Options': 'nosniff',
'X-XSS-Protection': '1; mode=block',
'Content-Security-Policy': "default-src 'self'; script-src 'self'; object-src 'none'; upgrade-insecure-requests",
'Referrer-Policy': 'strict-origin-when-cross-origin',
'Permissions-Policy': 'fullscreen=(self), camera=(), geolocation=()',
'Cross-Origin-Embedder-Policy': 'require-corp',
'Cross-Origin-Opener-Policy': 'same-origin',
'Cross-Origin-Resource-Policy': 'same-origin'
});
next();
});
What These Headers Do
1. Strict-Transport-Security
Strict-Transport-Security: max-age=63072000; preload
This tells browsers to only connect via HTTPS for the next 2 years (63072000 seconds). The preload directive allows your domain to be added to browsers' HSTS preload list, preventing even the first request from using insecure HTTP.
Why it matters: Protects against SSL stripping attacks by ensuring all future connections are encrypted.
2. X-Content-Type-Options
X-Content-Type-Options: nosniff
Prevents browsers from guessing (or "sniffing") the MIME type of a resource. This is important because misinterpreted files (e.g., JavaScript served as images) can be dangerous.
Why it matters: Reduces risk of executing malicious files disguised as safe content.
3. X-XSS-Protection
X-XSS-Protection: 1; mode=block
This enables the XSS protection filter in some older browsers. It tells the browser to block the page if an attack is detected.
Why it matters: Offers limited protection against cross-site scripting attacks in legacy environments.
4. Content-Security-Policy (CSP)
Content-Security-Policy: default-src 'self'
Purpose: Controls which resources (scripts, images, styles, etc.) can be loaded. Strong CSP rules help prevent XSS and data injection attacks.
5. Referrer-Policy
Referrer-Policy: strict-origin-when-cross-origin
Purpose: Limits what referrer information is shared when navigating away from your site, protecting user privacy and sensitive URLs.
6. Permissions-Policy (formerly Feature-Policy)
Permissions-Policy: fullscreen=(self), camera=(), geolocation=()
Purpose: Restricts browser APIs (like camera, geolocation, microphone, etc.) to only allowed origins or disables them entirely.
7. Cross-Origin-Embedder-Policy (COEP), Cross-Origin-Opener-Policy (COOP) & Cross-Origin-Resource-Policy (CORP)
These help isolate your site from other origins and protect against cross-origin attacks and speculative execution vulnerabilities (like Spectre).
Recommended configuration:
Cross-Origin-Embedder-Policy: require-corp
Cross-Origin-Opener-Policy: same-origin
Cross-Origin-Resource-Policy: same-origin
Using helmet — the easier way
Instead of manually adding headers, you can use helmet, a middleware package that sets many of these headers by default:
npm install helmet
Then in your app:
const helmet = require('helmet');
app.use(helmet());
You can also configure each header individually:
app.use(helmet.contentSecurityPolicy({
directives: {
defaultSrc: ["'self'"],
scriptSrc: ["'self'"]
}
}));
Conclusion
HTTP security headers are a simple but essential way to reduce your application’s attack surface. While no single measure guarantees complete protection, layering these headers with best practices (like input validation and HTTPS) significantly strengthens your web app’s defenses.
Start small, use tools like helmet, and review your security settings regularly—because protecting your users is not optional.
Top comments (0)