Guide

Security headers explained

HTTP security headers tell browsers how to treat your website: use HTTPS only, which resources may load, and who may embed your pages. They are cheap to add and easy to check.

How to check the headers your site sends

Open your site, then your browser's developer tools. In the Network tab, select the first request (the page itself) and look at the response headers. From a terminal, this shows the same thing:

curl -sI https://www.example.com/

Check more than the home page: login pages, checkout pages and error pages are often served differently.

The headers worth setting

Strict-Transport-Security

Tells browsers to use HTTPS only for your domain, for the time given in max-age. Add includeSubDomains only when every subdomain serves HTTPS, and treat the preload option as a long-term commitment that is slow to undo.

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

Content-Security-Policy

Lists where scripts, styles, images and other resources may load from, which limits the damage of injected content. Start with Content-Security-Policy-Report-Only to see what would break, then enforce. Its frame-ancestors directive controls who may embed your pages.

Content-Security-Policy: default-src 'self'; frame-ancestors 'none'

X-Content-Type-Options

Stops browsers from guessing a file type different from the one your server declares. There is one valid value, and it is safe to set everywhere.

X-Content-Type-Options: nosniff

X-Frame-Options

The older way to prevent other sites from framing your pages (clickjacking). CSP frame-ancestors replaces it; sending both is fine for older browsers.

X-Frame-Options: DENY

Referrer-Policy

Controls how much of the current URL is shared with other sites when a visitor follows a link. This value sends only the origin to other sites, and nothing when leaving HTTPS for HTTP.

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

Permissions-Policy

Turns off browser features your site does not use, including for embedded third-party content.

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

Cross-Origin-Opener-Policy

Keeps your pages in their own browsing context group, separate from windows opened by other sites. Test pop-up based sign-in and payment flows before enabling it.

Cross-Origin-Opener-Policy: same-origin

Headers to remove or reduce

  • X-Powered-By: Often reveals the exact PHP version. Set expose_php = Off in php.ini.
  • Server: Can reveal the web server and its version. Reduce it with server_tokens off (nginx) or ServerTokens Prod (Apache).
  • X-XSS-Protection: Deprecated and ignored by current browsers. Remove it, or send 0.

Where to set them

Set headers in one place, so every response gets them, including error pages:

  • nginx: add_header with the always parameter, in the server block.
  • Apache: Header always set (mod_headers), in the virtual host or .htaccess.
  • PHP: header() before any output, when you cannot change the server configuration.
  • CDN or hosting panel: many offer a response-header setting; check it does not duplicate headers set by the server.

Roll out one header at a time and re-check the site afterwards. A strict Content-Security-Policy in particular can break scripts, analytics or embedded content.

What headers do not tell you

A good header grade is one layer, not a verdict. It says nothing about an outdated PHP version, a vulnerable plugin or weak passwords. Headers are one part of our Website Security Audit, alongside TLS, cookies and e-mail authentication records.

Get a Security Assessment