HTTP security headers
In plain terms#
When a browser loads your site, your server sends back response headers alongside the page. A handful of them are instructions to the browser about how to defend the user: don't let this page be framed by an attacker, only ever connect over HTTPS, don't guess file types, block inline scripts. HTTP security headers are those instructions, and they're some of the cheapest, highest-leverage protections you can add.
Why it matters#
Missing headers don't announce themselves. The site works fine without them, but each gap enables a
class of attack: no Content-Security-Policy makes cross-site scripting far easier; no
X-Frame-Options/frame-ancestors allows clickjacking; no Strict-Transport-Security leaves users
exposed to protocol-downgrade attacks. They're a staple of the OWASP Secure Headers
Project, OWASP, the Open Worldwide Application
Security Project, is a widely-trusted nonprofit that publishes free security guidance.
Where it fits#
- Artifact: a running HTTP endpoint (your web app or API).
- Stage: against a deployed or preview environment, and you can enforce them declaratively
in your CDN/edge config (e.g. a Cloudflare
_headersfile) so they're reviewed like code.
How it works#
A scanner makes a request to your URL and inspects the response headers, checking that the important
ones are present and sensibly configured. The relevant set depends on the endpoint: a
browser-facing page cares about CSP, X-Frame-Options, and Referrer-Policy; a JSON API
cares more about CORS (Cross-Origin Resource Sharing) not being wildcard-open and about not caching
sensitive responses, flagging browser-only headers on an API is just noise.
Popular & reputable tools#
| Tool | Notes |
|---|---|
| Mozilla HTTP Observatory | Free scanner + letter-grade score |
| OWASP ZAP | OSS DAST; its passive scan flags header gaps |
| Nuclei | OSS; templates for header/exposure checks |
| securityheaders.com | Popular free online grader |
Common pitfalls#
- A too-strict CSP breaks the site. Content-Security-Policy is the highest-value header and the easiest to get wrong. Start in report-only mode, then enforce.
- Headers are environment-specific. They're set at the edge/server, so verify them against what's actually served, not just what you think is configured.
- Browser vs. API. Apply the right checklist to each, don't demand a CSP on a pure API.
headers control is a native check (no external tool) that fetches each of a component's hosts and evaluates its security headers against OWASP guidance, tuned by host type (browser vs api) so it doesn't flag browser-only headers on an API. Draugr even runs it against its own site in CI. See how to declare hosts in a Saga in the docs.
Keep learning#
- DAST, deeper runtime testing of the same endpoint
- TLS assessment, securing the connection headers ride on