Security Headers
Security headers are HTTP headers that help secure the communication between clients and servers. These headers protect APIs from a range of attacks such as cross-site scripting (XSS), clickjacking, content sniffing, and more.
Common Security Headers
Content-Security-Policy (CSP)
Prevents cross-site scripting (XSS) and code injection by defining which resources are allowed to load.
Content-Security-Policy: default-src 'none'; script-src 'self'; connect-src 'self' api.example.com
default-src 'none': block all by defaultscript-src 'self': only allow JS from the API's own domainconnect-src: restrict fetch/XHR/websocket destinations APIs that return HTML or are embedded in browsers benefit the most from CSP.
Strict-Transport-Security (HSTS)
Forces HTTPS-only connections to prevent man-in-the-middle (MITM) attacks.
Strict-Transport-Security: max-age=31536000; includeSubDomains
max-age: cache HTTPS requirement for 1 year (in seconds)includeSubDomains: enforce for all subdomains Only effective over HTTPS.
X-Content-Type-Options
Prevents MIME-type sniffing by browsers (which can lead to XSS).
X-Content-Type-Options: nosniff
Ensures the browser uses the declared Content-Type, rather than trying to guess it.
Access-Control-Allow-Origin (CORS)
Controls which domains are allowed to access the API via browser.
Access-Control-Allow-Origin: https://frontend.example.com
Crucial for browser-based clients; not typically needed for server-to-server calls.
Cache-Control
Prevent sensitive API responses (like tokens or PII) from being cached.
Cache-Control: no-store
Pragma: no-cache
Expires: 0
Example of Security Header
HTTP/1.1 200 OK
Content-Type: application/json
Strict-Transport-Security: max-age=31536000; includeSubDomains
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
Content-Security-Policy: default-src 'none'; connect-src 'self'
Referrer-Policy: no-referrer
Access-Control-Allow-Origin: https://frontend.example.com
Cache-Control: no-store
Pragma: no-cache
Node.js Implementation
const helmet = require("helmet");
app.use(helmet()); // adds most security headers
// Customize specific headers
app.use(
helmet.contentSecurityPolicy({
directives: {
defaultSrc: ["'none'"],
connectSrc: ["'self'", "api.example.com"],
},
})
);
app.get("/api/data", (req, res) => {
res.set("Cache-Control", "no-store");
res.json({ data: "Secure Data" });
});