how to set secure HTTP headers: the full list
Sets the full list of secure HTTP response headers on a web app: which headers to send, what values to use, and how to verify they are actually served. Use when hardening a new site, when a security scan flags missing headers, or when building a baseline header policy for all your services. Not for Content-Security-Policy in depth (separate skill), not for TLS configuration.
TL;DR
Six headers cover nearly everything: Strict-Transport-Security, Content-Security-Policy, X-Content-Type-Options, X-Frame-Options (or frame-ancestors), Referrer-Policy, and Permissions-Policy. Set them at your edge or reverse proxy so every response carries them, then verify with a header check. Start strict, loosen only what breaks.
how to set secure HTTP headers: the full listUse this when
- Hardening a new web app or API
- A security scan flags missing or weak response headers
- Building a standard header policy to apply across services
- You inherited a site with no security headers at all
Not for
- Content-Security-Policy tuning in depth (thats its own skill)
- TLS version and cipher configuration
- Request headers or authentication headers
Steps
1. Set Strict-Transport-Security.
Value: max-age=31536000; includeSubDomains. This tells browsers to only use HTTPS for your domain for the next year. Only set it once HTTPS works everywhere, including subdomains.
Expected: the header present on HTTPS responses.
2. Set Content-Security-Policy.
Start with a restrictive policy like default-src 'self' and loosen per the CSP skill. This is the most powerful header on the list and the most likely to break things, so test it.
Expected: CSP header present, site still fully functional.
3. Set X-Content-Type-Options.
Value: nosniff. Stops browsers from guessing content types, which blocks a class of drive-by attacks via mislabeled files.
Expected: header present, no behavior change for correctly served content.
4. Control framing.
Use frame-ancestors 'none' in your CSP, or the X-Frame-Options header with DENY, to block clickjacking. Pick one mechanism, CSP frame-ancestors is the modern one.
Expected: your pages refuse to load inside iframes on other sites.
5. Set Referrer-Policy.
Value: strict-origin-when-cross-origin is the sane default. It limits what URL information leaks to other sites when users follow links.
Expected: header present, analytics and OAuth flows still work.
6. Set Permissions-Policy.
Disable browser features you dont use: camera, microphone, geolocation, and similar. A restrictive default with explicit allows for the features you need.
Expected: header present, unused features blocked.
7. Apply at the edge and verify.
Set these at your CDN, load balancer, or reverse proxy so every response carries them, including error pages. Then check with a header inspection tool or a curl against your live site.
Expected: all six headers present on a normal page, an API response, and a 404 page.
Variant phrasings
What security headers should my website have
The six above. HSTS, CSP, nosniff, framing control, referrer policy, permissions policy.
Security scan says missing security headers
Work the list top to bottom, verify each one is served, and re-run the scan.
OWASP secure headers checklist
This list maps to the OWASP secure headers guidance. CSP and HSTS are the two that matter most.
Why it happens
Browsers ship with permissive defaults for compatibility, and every missing header is a default you accepted without choosing. The headers exist because whole attack classes (clickjacking, MIME sniffing, protocol downgrade) turned out to be fixable with a single response header. Setting them is the cheapest hardening there is.
Edge cases
- CSP breaks the app: this is the common one. Use report-only mode first, collect violation reports, then enforce. Never enforce an untested CSP on a Friday.
- HSTS includeSubDomains breaks an internal HTTP service: if a subdomain cant do HTTPS, drop includeSubDomains or fix the subdomain first. HSTS is hard to undo once browsers cache it.
- Third-party scripts need framing or features: allowlist the specific origins in frame-ancestors or permissions-policy rather than opening it up broadly.
- API-only services: APIs still benefit from nosniff, framing control, and referrer policy. HSTS matters if the API is browser-called. CSP matters less for pure JSON APIs but doesnt hurt.
Provenance
Resolved from the public thread: https://vectle.com/posts/pst_HXa7gihSvwIkOHUh7pIBSw
Maintainer review
No maintainer verification is recorded for this version.
This records the version a maintainer checked. It does not assert that the version is the latest upstream release.