Guide · Headers

Security headers: which ones actually matter?

Six useful headers, what each one really prevents, and why a missing header is not the same thing as a vulnerability.

Updated 10 September 2026 9 minute read

On this page
  1. Which ones matter
  2. Content Security Policy
  3. HSTS
  4. The three quiet ones
  5. Framing
  6. What no longer helps
  7. Missing is not compromised
  8. Technical sources
  9. Common questions

Short answer

Which security headers do you actually need?

Six matter in practice: HSTS, a Content Security Policy, nosniff, Referrer-Policy, Permissions-Policy and framing protection. The right priority depends on the site: a Content Security Policy has broad reach, but needs an inventory and a staged rollout.

A missing header is not a vulnerability. It is a protection the browser knows how to apply that nobody asked it to apply. The difference matters: it changes the priority you give the fix.

What a security header is

When a browser requests a page, the server returns the content and, ahead of it, a set of invisible instructions. Some of them tell the browser what it is allowed to do with the page.

These instructions require no browser-side software and add little network weight. Their real cost is configuration, an inventory of legitimate uses and verification on the live site.

What each header prevents, and how hard it is to put in place
HeaderWhat it preventsDifficulty
Content Security PolicyLoading scripts and resources nobody planned forReal: needs tuning
HSTSAn HTTP request once the browser knows the ruleLow, but hard to undo for a while
Framing protectionYour site displayed in a foreign frameLow
nosniffThe browser guessing a file’s typeLow
Referrer-PolicyAddress information passed to third-party sitesLow
Permissions-PolicyAccess to camera, microphone, locationLow

Worth remembering

nosniff, Referrer-Policy and framing protection are usually straightforward. Still verify the MIME types you serve, analytics needs and legitimate framing integrations.

Content Security Policy, the most useful and the most demanding

It answers one precise question: which resources is this page allowed to load? Scripts, styles, images, fonts, outgoing connections.

That is where its value comes from. If someone manages to inject a script into your page, through a comment, a form field or a compromised plugin, a well-set policy can stop it when no authorized source covers it. It reduces the impact of some injections; it does not fix the flaw that allowed the injection.

It is also the hardest to set, because it can break things that were working. Hence the method.

  1. Start in report-only mode

    The policy is sent but nothing is blocked. The browser only reports what it would have prevented.

  2. Collect what comes back

    Over a few days, on real traffic. You will discover services you had forgotten about.

  3. Allow what is legitimate

    Your analytics, your fonts, your booking system. One at a time, not with a wildcard.

  4. Switch to enforcing

    Once the reports dry up. Keep report-only running alongside for a while.

Careful

A policy switched straight to enforcing on a production site can make visible functions disappear with no error message for the visitor. Report-only mode exists precisely to avoid that.

Technical detail

The main difficulty on WordPress comes from inline JavaScript, which many themes and plugins produce. Allowing unsafe-inline for scripts makes the policy pass, and removes much of its value.

Depending on the application, the solution is to move code into allowed files or use nonces or hashes. It is real work worth planning, and it separates a cosmetic policy from a useful one.

HSTS, once HTTPS is certain

HSTS tells the browser: for this domain, use HTTPS only, for a stated duration. The browser remembers and will not even try HTTP again.

That closes a narrow but real window for a browser that already knows the rule. The first visit remains exposed unless the domain is preloaded or the browser has previously received HSTS over HTTPS.

Careful

HSTS is the only one of these instructions that is hard to undo. A browser that has remembered it will refuse HTTP for the whole stated duration, even if you change your mind.

Only set it once you have confirmed that all of the site, subdomains included if you cover them, answers correctly over HTTPS. Start with a short duration, then extend it.

The three quiet ones

They need less tuning than a Content Security Policy, but their values still have to match the site’s real functions.

nosniff stops the browser guessing a file’s type instead of trusting what the server declares. Without it, a file uploaded through a form can be interpreted as something other than intended.

Referrer-Policy limits what your site tells third-party sites. Without it, the full address of the page your visitor was leaving, parameters included, travels with them.

Permissions-Policy limits browser features your site does not need: camera, microphone, location, sensors. Keep the features that a legitimate integration actually uses.

Preventing framing

Without this protection, anyone can display your site inside a frame on their own domain, cover it with transparent elements, and get your visitors clicking on something other than what they think.

Two ways to say it: the frame-ancestors directive in a Content Security Policy delivered as an HTTP header, which is the modern form, or the historical X-Frame-Options header. The latter remains useful as a fallback for older clients.

Worth remembering

In browsers that enforce <code>frame-ancestors</code>, that directive overrides X-Frame-Options. If you send both for compatibility, give them a consistent intent.

What no longer helps

You will still see lists demanding X-XSS-Protection. That header drove a filter modern browsers have removed, because it created problems of its own. Requiring it today is habit, not security.

A report that flags it as a modern gap is worth reading carefully on everything else: it usually signals a copied list rather than an examination.

A missing header is not a compromised site

This distinction is the reason this guide exists.

A missing header describes a protection that is not switched on. It says nothing about whether a vulnerability exists, about the state of your administration accounts, or about what your code does with the data it receives. A site with all six headers can be vulnerable; a site with none may never have had an incident.

What headers change is what happens if a flaw exists elsewhere. They reduce what an attacker can get from it. That is damage reduction, not absence of risk.

Worth remembering

Headers do not make a site safe. They reduce what a flaw allows, if one exists. A good score only confirms the signals that were tested.

Common questions

Which one should I start with?

Start by inventorying MIME types, referrer needs, browser features and legitimate framing integrations. Apply the validated simple rules, then introduce Content Security Policy in report-only mode. Enable HSTS once HTTPS is reliable everywhere.

Is a WordPress plugin enough?

A plugin can configure them, but verify the headers actually received and avoid duplicates with the server or CDN. Content Security Policy still needs site-specific tuning.

My score is low. Is my site in danger?

Not necessarily. A low score reports protections that are not switched on, not a vulnerability that was found. It points to useful work, not to an emergency.

Do these headers slow the site down?

Their network cost is usually minimal. A Content Security Policy can, however, block an unauthorized resource from loading; you then need to correct the policy or the integration, depending on what is legitimate.

Talk about your configuration

A Repère Security audit examines your site within a scope you sign, and hands you findings reviewed by a person.

Talk to Repère Security What you can check yourself