Outrings
Web observability and evidence

What HTTP headers should every website send?

A prioritised list of response headers, what each one prevents, and which are safe to add without testing.

3 min read
Short answer

Four are safe to add today with essentially no risk: Strict-Transport-Security, X-Content-Type-Options, X-Frame-Options and Referrer-Policy. A Content Security Policy is the highest-value header and the only one that needs testing before enforcement.

Safe to add now

These four rarely break anything. If you do nothing else, do these.

Strict-Transport-Security

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

Tells browsers to use HTTPS for this domain for a year, even if a link says http://. This closes the window where a first request can be intercepted and downgraded.

One caution: includeSubDomains applies to every subdomain, so any internal or legacy host still serving plain HTTP becomes unreachable. Confirm that first, or omit the directive initially.

X-Content-Type-Options

X-Content-Type-Options: nosniff

Stops browsers guessing a resource's type from its content rather than trusting the declared Content-Type. Without it, a file that a browser decides looks like JavaScript may be executed as JavaScript — which is a real path for user-uploaded content to become an attack.

X-Frame-Options

X-Frame-Options: SAMEORIGIN

Prevents your pages being framed by other sites, which is the mechanism behind clickjacking. CSP's frame-ancestors supersedes it in modern browsers; sending both costs nothing and covers older ones.

Referrer-Policy

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

Controls how much URL information is sent when a visitor follows a link away. The default leaks full URLs to third parties, which matters if your paths contain anything identifying — reset tokens, order references, internal identifiers.

The one that needs testing

Content-Security-Policy

The highest-value header and the only one that can break a working site, because it enumerates what may load and execute. Deploy it in two stages.

Content-Security-Policy-Report-Only: default-src 'self'; report-uri /csp-report

Report-only enforces nothing and reports what it would have blocked. Run it for a week, read the reports, add the origins you genuinely need, and only then switch the header to enforcing.

Do not copy a strict CSP from an example. A policy has to be derived from what your site actually loads — which is exactly what the report-only phase tells you. Copied policies are the most common cause of self-inflicted breakage from security hardening.

Worth having, lower priority

HeaderPurpose
Permissions-PolicyDisables browser features you do not use — camera, microphone, geolocation
Cross-Origin-Opener-PolicyIsolates your browsing context from windows that open it
Cross-Origin-Resource-PolicyControls which origins may embed your resources
Cache-ControlNot security, but the header with the largest effect on real-world speed

Headers to stop sending

  • Server with a version — server_tokens off in nginx, ServerTokens Prod in Apache.
  • X-Powered-Byexpose_php = Off, or app.disable('x-powered-by').
  • X-XSS-Protection — a legacy header whose filter was removed from modern browsers and which could itself introduce issues. Remove it rather than setting it to 0 alongside a real CSP.

Checking what you actually send

curl -sIL https://example.com | grep -iE "strict-transport|content-security|x-frame|x-content-type|referrer-policy|permissions-policy"

The -L matters. Without it you are reading the headers of a redirect rather than of the page, which makes a correctly configured site look bare. And check the public URL rather than your origin — a CDN can add or strip headers in transit, and what the edge sends is what visitors get.

What our audit reports about this

Every item below is measured directly, not inferred. Run it against your own site and the result names the exact rule or header responsible.

  • Every security header present or absent, with its exact value rather than a pass mark.
  • Whether HSTS max-age is long enough to be meaningful and whether includeSubDomains is set.
  • CSP parsed for the directives that actually matter, including unsafe-inline and wildcard sources that weaken it.
  • Whether legacy or disclosing headers are still being sent, measured on the final response after redirects.

For agents and scripts, the same measurement is at /api/v1/security?url=yoursite.com — see the API documentation.

Related questions

Which single header should I add first?

HSTS, provided you already serve HTTPS everywhere. It is one line, it closes a real interception window, and it does not break anything as long as every subdomain covered by the policy is also on HTTPS.

Will a CSP break my site?

A copied one very likely will. One derived from a report-only run will not, because you built it from what your site actually loads. The two-stage rollout exists precisely because of this.

Do these headers help SEO?

Not directly. HTTPS is a ranking signal and the rest are not. They matter for user safety and for anyone evaluating your site technically, which is a different and also worthwhile audience.

My headers are configured but not appearing. Why?

Almost always a CDN or reverse proxy stripping or overriding them, or a rule scoped to a path that does not match. Measure the public URL rather than the origin — the served response is the only one that counts.

Read next

All 100 guides · How every check works · API for agents