21 Oct 2026 Two critical RCE bugs in PHP core (CVE-2026-109618, CVE-2026-109619). Fixed in 8.2.35 / 8.3.36 / 8.4.27 / 8.5.12. Is my PHP patched? →
Checklamp
Headers · what they prevent

Security headers: what each one prevents, in plain terms

Published · updated

Six response headers decide what a browser is allowed to do with your page. They are not a substitute for patching — but they are the difference between a small bug and a stolen session, and they take minutes to set.

Passive. Public responses only, nothing is attacked. No account. The result is on the page. Honest: if a value is hidden, we say so instead of guessing.
Reading public responses — usually 5–20 seconds

Read your own headers first

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

Anything missing from that output is a decision you have not made yet — the browser will fall back to its permissive default. Our checker grades each of the six separately and explains the consequence rather than the acronym.

The six, by consequence

HeaderWhat breaks without it
Strict-Transport-SecurityThe first request of a visit can travel over plain HTTP, and anyone on the network can read or rewrite it before the redirect happens.
Content-Security-PolicyAn injected script runs with your site's permissions — that is how a comment field becomes a session stealer.
X-Frame-OptionsYour pages can be embedded in someone else's frame, with your login form inside it, and clicks can be steered.
X-Content-Type-Options: nosniffA browser may treat an uploaded file as the type it guesses rather than the type you declared — an image that executes as a script.
Referrer-PolicyFull URLs — including tokens in query strings — leak to third-party sites through the Referer header.
Permissions-PolicyEmbedded or injected code can ask for camera, microphone or geolocation without your pages having a say.

Copy-ready configuration

nginx — in the server block, inside add_header with always so error pages get them too:

add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always;
add_header Content-Security-Policy "default-src 'self'; img-src 'self' data:; style-src 'self' 'unsafe-inline'; script-src 'self'" always;

Apache — with mod_headers enabled:

<IfModule mod_headers.c>
  Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"
  Header always set X-Content-Type-Options "nosniff"
  Header always set X-Frame-Options "SAMEORIGIN"
  Header always set Referrer-Policy "strict-origin-when-cross-origin"
  Header always set Permissions-Policy "camera=(), microphone=(), geolocation=()"
</IfModule>

For a site behind Cloudflare or another proxy, set them at the origin as well: a rule in the CDN is invisible to anything talking to your server directly.

Two ways to get CSP wrong

Shipping the example policy. The script-src 'self' above breaks every inline script, analytics tag and third-party widget on a real site. Start with Content-Security-Policy-Report-Only, collect the violation reports for a week, then enforce — the header takes effect on the day you switch, and every broken page is your own outage.

Turning on HSTS preload too early. includeSubDomains; preload is essentially irreversible: browsers will refuse plain HTTP for every subdomain for the lifetime of the entry, including the one subdomain that still has no certificate. Ship max-age first, extend it once you know every subdomain is HTTPS-only.

Do not chase the letter grade

Header graders reward max-age length, penalise 'unsafe-inline' and hand out an A to sites with an unpatched PHP build, because headers are all they can see. A site can score A and be exploitable the same afternoon. Fix the interpreter first (patch checklist), then the headers that block the specific trick your stack is exposed to.

Questions

Do security headers protect against SQL injection or RCE?

No. They constrain what a browser may do with a page. A bug that executes on the server — like the two PHP CVEs of 21 October 2026 — is not affected by any header you send.

Is X-Frame-Options still needed if I set frame-ancestors in CSP?

CSP frame-ancestors supersedes it in modern browsers, but old clients only understand X-Frame-Options. Sending both costs one line and avoids deciding which browsers you care about.

Our site is behind Cloudflare — where should the headers live?

At the origin. Cloudflare can add or transform headers, but a request that reaches the server directly bypasses the edge. Set them in nginx or Apache, then verify with curl against the origin IP.

Does HSTS break my certificate setup?

It enforces HTTPS for the max-age period, so any subdomain served over HTTP will stop working — that is the point, and also the risk. Test with a short max-age first.