Security Headers Checklist: CSP, HSTS, and Modern Web Hardening

FindMyTeam February 6, 2026

Most security reviews start with the same question: what does your site’s browser-facing security posture look like? One of the fastest, highest-signal answers comes from your HTTP response headers. They’re not “silver bullets”, but they do meaningfully reduce real-world risk—especially when combined with sane auth/session design and safe content handling.

This guide gives you:

  • A repeatable audit workflow (copy/paste commands).
  • A practical explanation of what each header does.
  • Safe starter defaults and what can break.
  • A decision checklist you can use in reviews.

If you’re doing a fast investigation on a suspicious site, start with Domain Lookup (DNS + basic security signals) and then use the commands below to verify headers directly.

Why security headers matter (in practice)

Headers help you limit damage from common web attack classes:

  • Clickjacking: invisible overlays trick users into clicking buttons they didn’t intend to.
  • XSS (cross-site scripting): attacker-controlled scripts run in your origin and steal sessions/data.
  • Mixed content & downgrade risk: users get bounced to insecure HTTP or load resources insecurely.
  • Privacy leakage: full URLs leak via referrers to third parties.

Even if you have perfect backend input validation, headers can still reduce blast radius when something slips through (or when third-party scripts misbehave).

Quick audit: grab headers in 10 seconds

Use curl to fetch response headers for your homepage (or any route):

curl -sSI https://example.com | sed -n '1,40p'

If you want to verify redirects + final destination headers:

curl -sSIL https://example.com | sed -n '1,80p'

Tip: test a few pages:

  • / (public landing)
  • /account (auth-required pages)
  • any route that renders untrusted content (comments, user profiles, uploads)

The core header set (what to use and why)

1) Strict-Transport-Security (HSTS)

Goal: force HTTPS for your domain after the first secure visit.

Recommended baseline:

Strict-Transport-Security: max-age=31536000; includeSubDomains; preload

Notes:

  • Don’t use preload unless you understand the operational impact (you’re committing to HTTPS everywhere, permanently enough to be on a preload list).
  • If you have any subdomain that cannot do HTTPS, don’t include includeSubDomains.

2) Content-Security-Policy (CSP)

Goal: control where scripts/styles/images can load from and reduce XSS impact.

Start with Report-Only to avoid breaking production:

Content-Security-Policy-Report-Only: default-src 'self'; script-src 'self'; object-src 'none'; base-uri 'self'; frame-ancestors 'none'

Then move to enforced CSP:

Content-Security-Policy: default-src 'self'; script-src 'self'; object-src 'none'; base-uri 'self'; frame-ancestors 'none'

Reality check:

  • CSP is often the “hardest” header because real apps load analytics, fonts, CDNs, and embedded content.
  • Resist script-src 'unsafe-inline' and script-src 'unsafe-eval' unless you absolutely must. If you have to allow inline scripts, prefer nonces.

3) Clickjacking: frame-ancestors / X-Frame-Options

Modern control is CSP:

Content-Security-Policy: ...; frame-ancestors 'none'

Legacy fallback:

X-Frame-Options: DENY

If you need embedding (e.g., your own subdomain embeds your app), use:

frame-ancestors 'self' https://trusted-embedder.example

4) X-Content-Type-Options

Prevents some MIME-sniffing behaviors:

X-Content-Type-Options: nosniff

5) Referrer-Policy

Avoid leaking full path/query strings to third-party sites:

Referrer-Policy: strict-origin-when-cross-origin

This is a sensible default for most sites.

6) Permissions-Policy

Disable browser features you don’t need:

Permissions-Policy: camera=(), microphone=(), geolocation=(), payment=()

Only enable what you actually use.

“Modern isolation” headers (advanced, but worth knowing)

These are increasingly relevant for apps with sensitive data or complex JS:

  • Cross-Origin-Opener-Policy (COOP)
  • Cross-Origin-Embedder-Policy (COEP)
  • Cross-Origin-Resource-Policy (CORP)

They help enforce stronger cross-origin isolation, but they can break third-party embeds and some resource loading patterns. Treat these as an intentional hardening phase, not a default you blindly copy into every app.

Common mistakes (and how to avoid them)

Mistake: “Set CSP to * and call it done”

A CSP that effectively allows everything provides minimal protection. If your CSP contains broad wildcards and unsafe-inline, it’s often worse than no CSP because it creates false confidence.

Mistake: forgetting redirects and subdomains

Your security headers should be consistent across:

  • The apex (example.com)
  • www.example.com
  • critical subdomains (auth, app, api)

Mistake: leaving framing enabled unintentionally

If your app is frameable by default, it’s clickjacking-friendly. Explicitly decide if you want embedding. Most products should default to not allowing it.

A practical review checklist

Use this when you’re auditing a site:

  • HTTPS enforced? (check redirects)
  • HSTS present and sane for your subdomain strategy
  • CSP present (at least Report-Only) and improving over time
  • frame-ancestors or X-Frame-Options configured intentionally
  • X-Content-Type-Options: nosniff
  • Referrer policy limits leakage
  • Permissions policy disables unused sensors/features

Want to combine headers with domain-level signals? Start with Domain Lookup (DNS + security hints), then use the Domain Performance page to understand the site’s technology footprint before you recommend fixes.

Final word: headers are a control layer, not a strategy

Security headers help you reduce exposure, but they don’t replace:

  • server-side validation and output encoding
  • safe auth/session handling
  • dependency hygiene and patching
  • logging + alerting (so you know when you’re under attack)

If you want a next step after headers, read: Phishing Triage Workflow.

Tools mentioned in this article

Run the same diagnostics to follow along with the guide.