Skip to content
All guides

WordPress Security Headers: What to Add and How

For developers 10 min readChecked October 26, 2026

Security headers are short instructions your server sends with each page that tell browsers how to protect your visitors. WordPress security headers cost nothing in speed and close whole families of attacks, but a few of them can break your site if you switch them on carelessly. Here is what to add, in a safe order.

What security headers are

An HTTP header is a line of text sent before the page itself. Visitors never see it, but their browser follows it. Security headers tell the browser to refuse certain risky behaviour, such as showing your site inside another site's frame or guessing a file's type.

WordPress does not send most of these by default, so you add them in your server config, in PHP or with a plugin.

Check what you send today

Look before you change. Open your browser's developer tools, go to the Network tab, reload and click the first request to see its response headers. From a terminal, curl -I https://example.com prints them. Online header scanners grade a site from the outside, and a free public check of your headers is available at /tools/security-check.

Test your home page, a post and a page that sets cookies, since a CDN or host may add headers to some responses but not others.

The WordPress security headers that matter

These are the ones worth your time, from easiest to most careful.

  • X-Content-Type-Options: nosniff stops browsers guessing a file's type, so an uploaded file cannot pretend to be a script.
  • X-Frame-Options: SAMEORIGIN stops other sites framing yours, which blocks clickjacking. A Content Security Policy frame-ancestors rule does the same job and is the modern form.
  • Referrer-Policy: strict-origin-when-cross-origin limits how much of your page address is passed to other sites.
  • Permissions-Policy turns off browser features your site never uses, such as camera, microphone and location.
  • Strict-Transport-Security (HSTS) tells browsers to use https only. Powerful, and hard to undo.
  • Content-Security-Policy (CSP) is an allow list for where scripts, styles, images and frames may load from. The strongest protection against injected scripts, and the easiest to get wrong.
  • Cross-Origin-Opener-Policy and Cross-Origin-Resource-Policy isolate your pages from other origins. Useful on some sites, but they can break embeds.

Easy wins first

Start with the four low risk headers: nosniff, X-Frame-Options, Referrer-Policy and Permissions-Policy. They almost never break a site. The one exception is X-Frame-Options if another site of yours legitimately shows your pages in a frame, or a page builder previews your pages in a frame on the same origin, which SAMEORIGIN permits.

The old X-XSS-Protection header is obsolete. Modern browsers ignore it, so do not rely on it.

HSTS without regret

HSTS makes browsers refuse plain http:// for your domain for the time you set. If part of your site or a subdomain is not ready for https, those visitors are locked out until the time runs out.

  1. 1Make sure every page and every subdomain you will cover works over https with a valid certificate.
  2. 2Start with a short max-age, such as one day, then one week.
  3. 3Raise it to one year once nothing breaks.
  4. 4Add includeSubDomains only when every subdomain is ready.
  5. 5Add preload only if you are sure. The preload list requires a max-age of at least one year with includeSubDomains, and removal takes months.

Content Security Policy in report-only mode

A CSP that is too strict breaks maps, chat widgets, fonts and payment forms. Use Content-Security-Policy-Report-Only first. Browsers then report what the policy would have blocked, but block nothing.

Browse the whole site, including forms, checkout and embedded video, for a few days. Add the sources you trust to the right directive. When the reports go quiet, switch to enforcing.

Add headers in Apache

On Apache, set headers in the site config or .htaccess with mod_headers. The always keyword makes them apply to error pages too.

Apache .htaccess
<IfModule mod_headers.c>
  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=()"
  # Only after testing on https:
  # Header always set Strict-Transport-Security "max-age=86400"
</IfModule>

Add headers in nginx

In nginx use add_header with always. One trap: an add_header inside a location block replaces the headers inherited from the server block, so repeat them wherever you use it.

nginx server block
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;
# Only after testing on https:
# add_header Strict-Transport-Security "max-age=86400" always;

Avoid duplicates and cache surprises

Your host, a CDN and a plugin can all send the same header. Two copies can confuse browsers, so set each header in one place. If a scanner shows a duplicate, switch it off in the other places.

Headers added by PHP are only sent on pages PHP generates. Files the server serves directly, and pages served from a full page cache, may not carry them, so test the same page as a first and a repeat visitor.

WordPress security headers: questions

Can security headers break my site?

Some can. HSTS and Content Security Policy are the risky ones, which is why you start with a short HSTS age and a report-only CSP.

Do security headers replace a security plugin or firewall?

No. Headers protect visitors inside their browsers, while lockouts, scanning and firewalls protect the server side. You want both.

How do I test my security headers?

Use the Network tab in your browser, run curl -I against your site, or use a free online header scanner. Check more than one page.

Do I need all of these headers?

Start with the four easy ones. Add HSTS when your whole site is on https, and a Content Security Policy when you can spend a week tuning it.

Why are my headers missing in the WordPress admin?

Many plugins only send headers on the public site, because the admin area loads scripts that a strict policy would block. Your server config can add headers to every response if you want them everywhere.

Protect your WordPress site free

Most of this guide is one switch in Stack Guard.