Topic 36

Security Headers and Defenses

Headers

A handful of HTTP response headers instruct the browser to enforce protections the server cannot enforce alone — forcing HTTPS, restricting scripts, controlling framing, and limiting what data leaks across origins. They are cheap to add and catch whole classes of attack as defense in depth, but they are precise: a wrong CSP breaks the app, a missing HSTS leaves a downgrade path.

This topic covers the headers worth setting on app.meridian.example and what each actually prevents — layered defense over correct code, not a substitute for it.

HSTS — Forcing HTTPS

Strict-Transport-Security tells browsers to only ever use HTTPS for the site, closing the downgrade and stripping gap from Chapter 2. With preloading, even the very first request is protected, because the browser knows to use HTTPS before it ever contacts the site. This is what makes "redirect to HTTPS" actually stick.

Content Security Policy

CSP is the strongest anti-XSS backstop: a whitelist of where scripts, styles, and connections may come from, so injected script has nowhere to run and nowhere to exfiltrate to. It is also the hardest header to author without breaking the app, which is why you roll it out in report-only mode first — collecting violations without enforcing — then tighten and enforce once the legitimate sources are known.

Framing and Referrer Controls

X-Frame-Options or CSP's frame-ancestors stop other sites from framing yours to trick clicks (clickjacking) — a one-line header that closes an attack most teams forget. Referrer-Policy stops leaking full URLs, and any tokens in them, to third parties, and Permissions-Policy disables browser features the app does not use.

A recommended header set for app.meridian.example
Strict-Transport-Security: max-age=63072000; includeSubDomains; preload
Content-Security-Policy: default-src 'self'; script-src 'self'; object-src 'none'; frame-ancestors 'none'
X-Content-Type-Options: nosniff
Referrer-Policy: strict-origin-when-cross-origin
Permissions-Policy: geolocation=(), microphone=(), camera=()
# roll CSP out as Content-Security-Policy-Report-Only first, fix violations, then enforce

This set forces HTTPS with HSTS, confines scripts and framing with a strict CSP, stops MIME sniffing, trims referrer leakage, and disables unused browser features. The one operational discipline that keeps it from breaking the app is rolling CSP out in report-only mode first: collect the violation reports, authorize the legitimate sources, and only then switch to enforcing.

Headers Are Defense in Depth

Treat headers as layered defense over correct code, never as the primary control. A CSP does not excuse un-encoded output, and HSTS does not excuse a bad TLS configuration — the headers catch what slips through and contain what goes wrong, but the application still has to be right underneath them. Their value is that they are cheap and they fail safe.

Common Mistakes
  • No HSTS, leaving the first-request downgrade open even when the site redirects to HTTPS.
  • Enforcing a strict CSP without a report-only shakeout, breaking the app and getting the policy loosened to uselessness.
  • Forgetting anti-framing headers and remaining clickjackable, or leaking sensitive URLs via a permissive Referrer-Policy.
  • Treating headers as the primary defense rather than defense in depth — a CSP does not excuse un-encoded output.
  • Setting a CSP so loose (allowing unsafe-inline everywhere) that it stops containing XSS at all.
Best Practices
  • Set HSTS — and preload it once confident — and enforce HTTPS site-wide so headers cannot be stripped.
  • Roll out a strict CSP in report-only mode, fix violations, then enforce; keep it tight (default-src 'self', no inline script).
  • Add frame-ancestors or X-Frame-Options, a restrictive Referrer-Policy, and Permissions-Policy, and set the secure cookie flags.
  • Treat headers as layered defense over correct code, and monitor CSP reports as an XSS early-warning signal.
  • Scan the deployed site periodically to confirm the headers are present and strict.
Comparable toolsTransport / script Strict-Transport-Security · Content-Security-PolicyFraming / referrer X-Frame-Options / frame-ancestors · Referrer-Policy · Permissions-PolicyScanners securityheaders.com · Mozilla Observatory

Knowledge Check

Why is HSTS needed even when the server already redirects HTTP to HTTPS?

  • The first HTTP request is downgradeable; HSTS closes it
  • Redirects are slower than serving HTTPS directly
  • HSTS encrypts the certificate's private key
  • Without HSTS the server cannot present a valid TLS certificate

Why roll out a Content Security Policy in report-only mode first?

  • To discover which sources it would break before enforcing
  • Report-only mode is more secure than enforcing mode
  • CSP cannot be enforced without a report-only period by the spec
  • Report-only mode encrypts the page contents

What is the right way to think about security headers?

  • Defense in depth — they don't excuse bad code or TLS
  • They are the primary defense and replace output encoding
  • They only matter for static websites
  • A single header can secure the entire application

You got correct