Skip to content

HTTP Security Headers in WordPress: CSP, HSTS and X-Frame-Options

4 min read

HTTP Security Headers in WordPress: CSP, HSTS and X-Frame-Options – wordpress security headers

You can protect your WordPress site with plugins, strong passwords and backups, but if your visitors’ browser gets no clear instructions on how to treat your site, you leave a door ajar. This is exactly where WordPress security headers come in: small directives the server sends along with every page, telling the browser what it is and isn’t allowed to do. They’re invisible to the user, yet they make the difference between a resilient site and an easily exploited one.

What WordPress security headers are and why they matter

An HTTP header is a line of metadata the server sends before the actual content. Security headers are a subset that instructs the browser to apply defensive rules: force HTTPS, block unauthorized scripts, or refuse to load the site inside a foreign iframe.

Their advantage is that they act at the browser level, meaning before an attack even gets to run code on your page. Think of them as successive layers of defense, each covering a different type of risk. The good news: you don’t need a heavy plugin for them, just a few lines of configuration placed in the right spot.

Diagram of the WordPress security headers layers: HSTS, CSP and X-Frame-Options.WordPress Security HeadersHSTS: force HTTPSCSP: block foreign scriptsX-Frame-Options: anti-clickjackingX-Content-Type-Options: nosniffReferrer-Policy: limited data
The layers of WordPress security headers the server sends to the browser.

HSTS: force the encrypted connection

HSTS (HTTP Strict Transport Security) tells the browser to talk to your site over HTTPS only, even if someone types the address with “http://”. Once the rule is remembered, the browser doesn’t even make that first insecure request, closing the window in which an attacker could intercept the traffic.

A typical value looks like this: Strict-Transport-Security: max-age=31536000. For WordPress, the recommendation is to start without preload and without includeSubDomains, so you don’t accidentally block subdomains that still run on HTTP. You add those later, once you’re sure the whole ecosystem is on HTTPS.

Watch the SSL certificate

HSTS assumes a valid SSL certificate renewed on time. If the certificate expires, visitors won’t be able to reach the site at all until you fix it, because the browser flatly refuses the insecure connection. Monitor its expiry and use automatic renewal.

CSP: the most powerful header, but also the most sensitive

Content Security Policy (CSP) defines exactly which sources of scripts, styles, images or fonts the page is allowed to load. It’s the most effective barrier against XSS attacks, because a script injected from an unauthorized source simply won’t run.

The catch is that an overly strict CSP can block legitimate resources: Google Fonts, an analytics script, or even inline styles from the theme. That’s why the golden rule is to start in Content-Security-Policy-Report-Only mode, which only reports violations without blocking anything, and then switch to the variant that actually enforces the policy. You can read how it works in detail in the web.dev documentation on CSP.

For the inline scripts you truly need — like the one that prevents the white flash when switching to dark mode — use a hash or a nonce, not unsafe-inline, which would cancel half the benefit.

X-Frame-Options: a shield against clickjacking

Clickjacking means someone loads your site inside a transparent iframe, layered over another page, to trick you into clicking buttons without realizing it. The X-Frame-Options: SAMEORIGIN header forbids your pages from being loaded in iframes on other domains and stops this type of attack from the start.

The other headers worth adding

Beyond the big three, a few short headers close off common risks:

  • X-Content-Type-Options: nosniff — stops the browser from “guessing” a file’s type and executing it incorrectly.
  • Referrer-Policy: strict-origin-when-cross-origin — limits the information about your address sent to external sites.
  • Permissions-Policy — disables sensitive APIs (camera, microphone, geolocation) your site doesn’t need.

You can check your whole configuration’s score with a free tool like securityheaders.com, which gives you a grade from F to A+ and shows exactly what’s missing.

How to add them correctly in WordPress

You have two main places to set them: at the server level (the .htaccess file on Apache or LiteSpeed, or the Nginx config) or from PHP, through WordPress’s send_headers hook. The server-level option is preferable, because it applies to all responses, including static files.

Whatever the method, test after every change: open the browser console, check the Network tab, and confirm you haven’t broken any styles or features. A misconfigured CSP can “whiten” half the site with no visible error message. If you want a complete approach, with every layer set up and tested, see our WordPress security service or request a free audit where we check exactly which headers are missing from your site.

Security headers don’t replace a firewall or backups, but they’re among the cheapest and most effective measures you can take: a few lines of configuration that immediately raise your site’s resilience. Add them gradually, test after each step, and your site will become visibly harder to attack.