← Guides

WordPress Security Headers: Copy-Paste Setup for .htaccess, nginx, Cloudflare or a Plugin

Most WordPress sites send none of the standard security headers, and many of the plugins that add them only cover PHP pages. Here's where to set them, values that don't break the dashboard or WooCommerce, and how to check the result.

Pick one place to set them

From best to worst:

  1. The web server (Apache or LiteSpeed .htaccess, or nginx). This covers static files and cached pages too.
  2. Cloudflare, if your site is behind it.
  3. Your host's panel, if it has a headers setting.
  4. A must-use plugin in PHP, when you can't touch the server.

Use only one. If the same header comes from two places, browsers get it twice, and two Content-Security-Policy headers are both enforced, which quietly breaks scripts.

Apache or LiteSpeed (.htaccess)

Most cPanel hosts run one of these. Add this to the .htaccess file in your WordPress root, above the # BEGIN WordPress line, because WordPress rewrites that block:

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

Keep the word always, or Apache skips the headers on redirects and error pages. If nothing changes, your host may have mod_headers off; ask them.

nginx

In the site's server block:

add_header Strict-Transport-Security "max-age=300" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always;

Watch out: if a location block has its own add_header, nginx drops the server-level ones for that location. Repeat them there or use an include file. Reload with sudo nginx -t && sudo systemctl reload nginx.

Cloudflare

Go to Rules, then Transform Rules, then Modify Response Header. Create a rule for all incoming requests and add one "Set static" line per header above. Also turn on Always Use HTTPS and set SSL/TLS to Full (strict).

Must-use plugin (no server access)

Save as wp-content/mu-plugins/security-headers.php. Must-use plugins load automatically and can't be switched off by accident:

<?php
add_action('send_headers', function () {
  header('Strict-Transport-Security: max-age=300');
  header('X-Frame-Options: SAMEORIGIN');
  header('X-Content-Type-Options: nosniff');
  header('Referrer-Policy: strict-origin-when-cross-origin');
  header('Permissions-Policy: camera=(), microphone=(), geolocation=()');
});

This only covers pages WordPress builds, not images or files served straight from disk, and a page cache may serve old copies until you purge it.

Why these values

Content-Security-Policy on WordPress

Core, themes, and plugins print inline scripts, so a strict CSP takes real work. Two directives are safe right away:

Content-Security-Policy: frame-ancestors 'self'; upgrade-insecure-requests

For a full policy, start with Content-Security-Policy-Report-Only, click through the site, wp-admin, checkout, and forms with the browser console open, add each legitimate source (Stripe, PayPal, Google Analytics, reCAPTCHA, fonts), and only then switch to enforcing.

Check the result from outside

curl -sI https://yoursite.com | grep -iE "strict-transport|x-frame|x-content|referrer|permissions|content-security"

Check from outside wp-admin, after purging your cache plugin and any CDN cache. Hosting elsewhere? See our security headers checker guide for Netlify, Vercel, and Cloudflare configs.

Check it the fast way

Want a second opinion in under a minute? Scan your site free with SiteShield. It checks which security headers your WordPress site actually sends (HSTS, CSP, X-Frame-Options, X-Content-Type-Options, Referrer-Policy, Permissions-Policy), plus SSL, SPF, DMARC, and privacy basics and shows your score and every issue found. If you'd rather skip the trial and error, the $14 fix bundle gives you copy-paste fixes written for your exact site.

Check your site free

SiteShield by Telekeen · Telekeen Communications