← Back to all articles

HTTP Security Headers to Check Before Launch

HTTPSecurity

Six headers to set

HeaderProtectsRecommended
Strict-Transport-SecurityForces HTTPS, stops downgrademax-age=31536000; includeSubDomains; preload
Content-Security-PolicyLimits loadable resources, blocks XSSTighten gradually per app
X-Content-Type-OptionsStops MIME sniffingnosniff
X-Frame-Options / frame-ancestorsStops clickjackingDENY or SAMEORIGIN
Referrer-PolicyLimits referrer leakagestrict-origin-when-cross-origin
Permissions-PolicyRevokes unneeded browser powerDisable camera/mic as needed

Don't write CSP in one shot

Start with Content-Security-Policy-Report-Only to catch false positives, then switch to enforcing. Prefer a nonce or hash over unsafe-inline, and list external script domains explicitly.

Two common mistakes

  • HSTS is hard to undo: with includeSubDomains + preload, subdomains are locked out of HTTP for a long time — confirm every subdomain supports HTTPS first;
  • Set only at the edge: if the CDN adds the header but the origin doesn't, an attacker hitting the origin bypasses it. Set it at both layers.

How to verify

Run curl -I https://your-domain to read response headers, or use an online header scan. Make sure core flows work before tightening.

Real-world cases: three integrations blocked by security headers

  1. An iframe embedding goes blank: the site sends X-Frame-Options: DENY, so a partner's embed shows nothing. If embedding is genuinely needed, switch to CSP frame-ancestors listing the allowed origins.
  2. A CDN script blocked by CSP: Content-Security-Policy was added but script-src omits the CDN domain, breaking page functionality. Roll CSP out with Content-Security-Policy-Report-Only first, then enforce.
  3. HSTS locking down a test domain: Strict-Transport-Security with includeSubDomains on a wildcard domain where a test subdomain lacks HTTPS leaves browsers refusing downgrades for a long time. Confirm every subdomain supports HTTPS first.

FAQ

Where should security headers be set? At the edge (CDN or gateway) so no service forgets, though CSP usually needs per-app tuning. What is X-Content-Type-Options for? It stops browsers sniffing content types and executing an uploaded text file as a script. Does CSP prevent XSS? It substantially reduces risk but does not replace output escaping and input validation. Which Referrer-Policy? strict-origin-when-cross-origin — full referrer same-origin, origin only cross-origin.

Rolling out CSP in stages

A misconfigured CSP breaks pages instantly, so phase it in:

  1. Start with Report-Only: use Content-Security-Policy-Report-Only to observe real violations for a week or two without blocking;
  2. Collect reports: configure report-to / report-uri and analyse centrally, separating inline scripts you must fix from third-party resources;
  3. Eliminate inline scripts: move them to files or use nonces — leaving unsafe-inline in place sharply reduces CSP's XSS value;
  4. Tighten directives gradually: lock down default-src and script-src first, then add img-src, connect-src and frame-ancestors;
  5. Enforce last: switch to enforcing once violation reports are clear, keeping a rollback switch.

The minimum header set is Content-Security-Policy, Strict-Transport-Security, X-Content-Type-Options, Referrer-Policy and Permissions-Policy. Put them on the deployment checklist and inject at the platform level rather than per service.

From audit to routine practice

Security headers pay off through long-term consistency, not a single tidy configuration.

  1. Start with a baseline scan: use a scanner or online check to list missing or misconfigured headers, ordered by impact, instead of changing everything at once.
  2. Codify into deployment templates: put header configuration in infrastructure code or the gateway so the platform injects it and new services cannot forget it. Manually editing each server does not survive.
  3. Add a regression check: validate in the release pipeline that key headers exist with expected values, or a refactor will quietly drop them.
  4. Review the policy periodically: browser standards and business dependencies change; revisit every six months and consider tightening.
  5. Record exceptions: any relaxation made for compatibility needs a reason, an owner and an expiry date, or temporary compromises become permanent holes.

With all five, headers become a controlled routine rather than a one-off task, and you can produce evidence for audits.