Security headers remain the cheapest hardening available: a few directives that block entire classes of injection, clickjacking and transport attacks, configured once at the edge. In 2026 the baseline set has stabilized, and the work is mostly removing the legacy exceptions that accumulated when they were first added.

The baseline set

Content-Security-Policy, Strict-Transport-Security, X-Content-Type-Options, Referrer-Policy, and a frame-ancestor directive in CSP collectively prevent clickjacking, MIME sniffing, downgrade attacks, and most injected script execution.

Roll out CSP in report-only

Enforcing CSP on day one breaks inline scripts and third-party tags indiscriminately. Start in report-only mode, collect violations, fix the legitimate ones, then flip to enforcement with a clean signal.

Security illustration
Illustration: Security — photo via Unsplash

Third parties are the hard part

Analytics, ads, and embedded widgets complicate CSP more than your own code. Audit whether each third party earns its script allowance, because every exception widens the injection surface you just worked to close.

The baseline set

Every web application should send a strict Content-Security-Policy (starting report-only, then enforcing), HSTS with a long max-age once HTTPS is fully settled, X-Content-Type-Options: nosniff, a Referrer-Policy appropriate to the product, Permissions-Policy disabling unused capabilities like camera and microphone, and frame-ancestors to replace X-Frame-Options. Together these neutralize most reflected XSS impact, MIME sniffing, unwanted embedding and cross-origin leakage without touching application code.

Rolling out CSP without breaking the app

CSP is where most rollouts stall, because real applications load scripts, frames and images from a web of origins. The working sequence: deploy report-only with report-uri collection, review violations for two weeks, fix or allowlist each genuine source, then flip to enforcement with a documented exception process. The teams that succeed treat CSP exceptions as temporary tickets with expiry dates — an allowlist that never expires is a policy that has quietly given up.

Security illustration
Illustration: Security — photo via Unsplash

Key takeaways

  • Baseline: CSP, HSTS, nosniff, Referrer-Policy, Permissions-Policy, frame-ancestors.
  • Roll out CSP report-only first; fix real violations before enforcing.
  • Every CSP exception should be a ticket with an expiry date.

Final thoughts

Security headers deliver defense-in-depth at near-zero cost, and the only reason every app does not send them is the accumulated weight of exceptions nobody revisited — which is a review away from being fixed.

Sources & further reading