How to Configure Secure Headers and a Content Security Policy
Add HSTS, nosniff, referrer, and framing protections, then author a Content Security Policy and roll it out safely with report-only mode before enforcing it to mitigate XSS.
What and why
HTTP security headers instruct the browser to enforce protections the server cannot. The most important is a Content Security Policy (CSP), which restricts where scripts, styles, and other resources may load from, sharply reducing the impact of cross-site scripting (XSS). Other headers harden transport and framing.
Prerequisites
- A web app served over HTTPS.
- Browser developer tools to read console errors.
- Basic understanding of HTTP headers.
Steps
1. Enable HSTS
HTTP Strict Transport Security forces HTTPS:
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
Only set this once HTTPS is solid, because browsers will refuse plain HTTP for the max-age duration.
2. Set framing and content-type protections
X-Content-Type-Options: nosniff
Referrer-Policy: strict-origin-when-cross-origin
Prefer the CSP frame-ancestors directive over the legacy X-Frame-Options header to control framing.
3. Draft a Content Security Policy
Start restrictive and allow only what you need:
Content-Security-Policy: default-src 'self'; script-src 'self'; style-src 'self'; img-src 'self' data:; frame-ancestors 'none'; base-uri 'self'
For inline scripts you cannot remove, use a per-request nonce (script-src 'self' 'nonce-<random>') rather than unsafe-inline.
4. Roll out CSP in report-only mode
Deploy with the report-only header first so violations are logged but nothing breaks:
Content-Security-Policy-Report-Only: default-src 'self'; report-uri /csp-reports
Collect reports, find legitimate resources the policy blocks, and add them.
5. Enforce and tighten the policy
Once reports are clean, switch to the enforcing Content-Security-Policy header. In Express, the helmet middleware sets these headers with sensible defaults:
const helmet = require('helmet');
app.use(helmet());
In Nginx, use add_header directives in the server block.
Verification
- Response headers include HSTS, nosniff, and a CSP.
- The browser console shows no unexpected CSP violations.
- An injected
<script>from another origin is blocked.
Next Steps
Add Subresource Integrity for third-party scripts, scan headers with an online analyzer, and review the CSP whenever you add new third-party resources so the policy stays both strict and functional.
Prerequisites
- A web application served over HTTPS
- Browser developer tools
- Basic HTTP header knowledge
Steps
- 1Enable HSTS
- 2Set framing and content-type protections
- 3Draft a Content Security Policy
- 4Roll out CSP in report-only mode
- 5Enforce and tighten the policy