Guides · HTTP
HTTP Security Headers Explained
What HTTP security headers do, which ones every site should send, and a sensible baseline for HSTS, CSP, X-Content-Type-Options, X-Frame-Options, Referrer-Policy, and Permissions-Policy.
By Cody · 8 min read · Published
The short version
HTTP security headers are response headers that tell the browser how to treat your page more safely. They do not change what the page says — they change the rules the browser enforces around it: force HTTPS, refuse to be framed, stop guessing file types, and restrict where scripts may come from.
None of them are visible to a visitor, and most are a single line of server config. Together they close off entire categories of attack — clickjacking, protocol downgrade, MIME confusion, and cross-site scripting amplification — for very little effort. The rule of thumb: send a small, well-understood set on every response rather than a long list you cannot explain.
The headers that matter
These are the headers worth sending on a normal website, what each one does, and a sensible starting value:
| Header | What it does | Sensible baseline |
|---|---|---|
| Strict-Transport-Security | Forces the browser to use HTTPS for future visits. | max-age=31536000; includeSubDomains |
| Content-Security-Policy | Restricts where scripts, styles, frames, and other resources may load from. | Start in report-only, then enforce a tight policy |
| X-Content-Type-Options | Stops the browser from MIME-sniffing a response into something executable. | nosniff |
| X-Frame-Options | Blocks your page from being embedded in a frame (clickjacking defense). | DENY or SAMEORIGIN |
| Referrer-Policy | Controls how much of the URL is sent as the referrer to other sites. | strict-origin-when-cross-origin |
| Permissions-Policy | Switches off browser features (camera, geolocation, etc.) you do not use. | camera=(), geolocation=(), microphone=() |
| Cross-Origin-Opener-Policy | Isolates your page into its own browsing-context group. | same-origin |
A sensible baseline
For most sites, four headers carry the bulk of the value and are safe to turn on with little risk:
- Strict-Transport-Security — once HTTPS is solid everywhere.
- X-Content-Type-Options: nosniff — no reason not to.
- Referrer-Policy — protects user privacy and internal URLs.
- X-Frame-Options (or CSP
frame-ancestors) — stops clickjacking.
Content-Security-Policy is the highest-value header but also the easiest to break a site with, so it gets its own rollout: ship it in Content-Security-Policy-Report-Only first, collect the violation reports it generates, fix or allowlist the legitimate sources, and only then switch to the enforcing Content-Security-Policy header.
HSTS, in a little more depth
Strict-Transport-Security (HSTS) is worth understanding because its mistakes are sticky. It has three parts:
max-age— how long, in seconds, the browser should remember to force HTTPS. A year (31536000) is typical once you are confident.includeSubDomains— applies the rule to every subdomain. Only add it when all subdomains can serve HTTPS, or you will lock out the ones that cannot.preload— opts your domain into a list browsers ship in their source code. It is powerful but hard to reverse, so treat it as a long-term commitment, not a default.
Because HSTS only takes effect after the browser has seen one good HTTPS response, it layers on top of a valid certificate — it does not create one. If the certificate is expired or untrusted, fix that first.
Common findings and what they mean
When you check a site's headers, these are the results you will see most often:
| Finding | What it means |
|---|---|
| No Strict-Transport-Security | The site allows a first request over plain HTTP, leaving room for downgrade attacks. |
| No Content-Security-Policy | No restriction on where scripts load from; an injected tag is more likely to run. |
| Missing nosniff | The browser may reinterpret a response's type and execute it unexpectedly. |
| No frame protection | The page can be embedded by another site for clickjacking. |
| Overly broad CSP (unsafe-inline) | A policy exists but allows inline scripts, which removes much of its protection. |
How to check your headers
Use the HTTP security header checker to send a request, follow any redirects, and read back the response headers a real browser would receive — including which security headers are present and which are missing. It reports the status and redirect chain too, so you can confirm an HTTP request is being upgraded to HTTPS the way you expect.
Because these headers ride on the HTTPS response, it pairs naturally with the TLS certificate checker: confirm the certificate is valid and trusted first, then confirm the headers riding on top of it are in place.
A solid set of security headers
- Example input
curl -I https://example.com- Example result
HTTP/2 200 strict-transport-security: max-age=31536000; includeSubDomains content-security-policy: default-src 'self'; frame-ancestors 'none' x-content-type-options: nosniff x-frame-options: DENY referrer-policy: strict-origin-when-cross-origin permissions-policy: camera=(), geolocation=(), microphone=()
Four lines of config cover HTTPS enforcement, resource restriction, MIME safety, clickjacking, referrer leakage, and unused browser features.
Related tools
FAQ
What are HTTP security headers?
HTTP security headers are response headers a server sends alongside a page to tell the browser how to behave more safely — whether to force HTTPS, which sources may load scripts, whether the page can be framed, and so on. They do not change the content of the page; they change the rules the browser applies to it, which closes off whole classes of attacks like clickjacking, protocol downgrade, and MIME-type confusion.
Which security headers should every site have?
A good baseline is four headers: Strict-Transport-Security (force HTTPS), X-Content-Type-Options: nosniff (stop MIME sniffing), Referrer-Policy (limit referrer leakage), and a Content-Security-Policy (control where resources load from). X-Frame-Options or a CSP frame-ancestors directive protects against clickjacking. Permissions-Policy is a useful extra to switch off browser features you do not use.
What is the difference between CSP and X-Frame-Options?
X-Frame-Options is a single-purpose, older header that only controls whether your page can be embedded in a frame (to prevent clickjacking). Content-Security-Policy is a broad policy language that can do the same job through its frame-ancestors directive and also control scripts, styles, images, connections, and more. Modern sites use CSP frame-ancestors and keep X-Frame-Options only for older browsers.
Is HSTS safe to enable?
Yes, once your site reliably serves HTTPS on the apex and every subdomain you intend to cover. Start with a short max-age (for example 300 seconds) to confirm nothing breaks, then raise it to a year (31536000). Be careful with includeSubDomains and especially the preload flag — preload is hard to undo, because browsers ship the entry in their source, so only preload when every subdomain can do HTTPS now and in the future.
What does X-Content-Type-Options: nosniff do?
It tells the browser to trust the Content-Type you declared instead of guessing (sniffing) the type from the bytes. Without it, a browser might decide a file you served as text is actually a script and execute it, which is a real attack vector for user-uploaded content. The header takes a single value, nosniff, and there is almost never a reason not to send it.
Do security headers replace HTTPS or a firewall?
No. Security headers are defense in depth, not a replacement for TLS, patching, input validation, or a WAF. HSTS in particular only helps after the browser has seen your site once over HTTPS; it assumes you already have a valid certificate. Think of headers as instructions that make a browser enforce good habits, layered on top of the rest of your security.
How do I add security headers to my site?
Headers are set wherever your responses are produced: in the web server config (nginx add_header, Apache Header set), at a CDN or reverse proxy edge, or in your application framework. Set them once at the edge so every route is covered consistently. Add a strict Content-Security-Policy carefully — deploy it in Content-Security-Policy-Report-Only first, watch for violations, then enforce.
Last reviewed: 2026-06-29.