Add Security Headers: Nginx, Apache & Cloudflare
Copy-paste configs for HSTS, CSP, X-Frame-Options and friends on Nginx, Apache and Cloudflare - plus how to verify they're actually live.
Short answer
Add security headers at the edge you control: Nginx add_header, Apache Header always set, or Cloudflare Transform Rules. Verify with curl -I and a free grade. Start with HSTS, nosniff, framing, and Referrer-Policy; add CSP carefully.
Where to put them
Headers only help if they appear on the responses users actually get. Prefer the reverse proxy or CDN in front of the app so static errors and app responses both carry them.
Setting headers only inside the app framework leaves 404s, static assets, and edge-cached responses unguarded. Fix the layer that terminates TLS for real visitors.
Nginx
Use add_header with the always flag so error responses also include the headers. Put HSTS only on the HTTPS server block. Reload and test from outside.
Duplicate add_header blocks in nested locations can drop parent headers - a classic Nginx footgun. Keep the baseline in one place you can audit.
Apache and Cloudflare
Apache: mod_headers with Header always set. Cloudflare: Transform Rules to set response headers when traffic is proxied. Origin still matters for direct hits and non-proxied hosts.
If you use both CDN and origin headers, decide which layer is source of truth so you do not fight yourself on every deploy.
Verify every time
curl -sI https://yoursite and find the headers you expect. Then re-run a passive scan. Deploy pipelines should fail if critical headers disappear - silent header loss is a common regression after "harmless" CDN changes.
Screenshot or archive the curl output next to the change ticket. Future you will thank you when someone asks "when did HSTS break?"
Config to copy
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
Paste carefully. Test on staging first if the setting can lock users out.
What to do this week
- Pick one edge of truth (Nginx, Apache, or CDN) for the baseline headers.
- Ship HSTS, nosniff, framing control, and Referrer-Policy first.
- curl -sI production and confirm each header is present.
- Add a CI or post-deploy check that fails if HSTS vanishes.
Put headers where every response passes. Then prove they are live.
Update log (1)
2026-05-04Editorial form rewrite for length and uniqueness.
Sources + verification
Practical guidance based on mainstream browser behavior, common reverse-proxy configuration, and widely published RFCs and vendor docs. Verify on your own stack with curl, browser devtools, and a re-scan after each change.