Add Strict Security Headers to Your WordPress Site

This Q&A shows how to apply strict HTTP security headers like HSTS, CSP, X-Frame-Options in WordPress. It covers server level changes for Apache and Nginx and explains how plugins use the send_headers hook. You’ll see code snippets and tips to avoid header conflicts.

How do I set strict HTTP security headers (HSTS, CSP) in WordPress?

Configure Your Web Server (Recommended)

The most dependable way to apply headers is at the web server level, such as Apache or Nginx. That way, every request carries the headers, no matter what WordPress does.

Apache

Enable mod_headers and add to your .htaccess:

<IfModule mod_headers.c>
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
Header always set Content-Security-Policy "default-src 'self';"
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 "geolocation=(), microphone=(), camera=()"
</IfModule>

Nginx

Edit your server block (often in /etc/nginx/sites-available/) and add:

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

Explanation of Headers

  • Strict-Transport-Security (HSTS): Forces browsers to use HTTPS only.
    • max-age: Duration in seconds; 31536000 is one year.
    • includeSubDomains: Applies to all subdomains.
    • preload: Lets you add the site to browser preload lists.
  • Content-Security-Policy (CSP): Defines trusted sources for scripts, images, styles, and more. A simple start is default-src 'self', but you may need to adjust for external resources.
  • X-Frame-Options: Stops clickjacking by blocking framing from other origins (SAMEORIGIN).
  • X-Content-Type-Options: Disables MIME-sniffing (nosniff).
  • Referrer-Policy: Limits referrer details; strict-origin-when-cross-origin sends only the origin when crossing domains.
  • Permissions-Policy: Manages browser features; for example, geolocation=(), microphone=(), camera=() disables those features.

Using a Plugin

Some plugins let you add headers without touching server files. Popular choices include:

  • Really Simple SSL – Adds HSTS and other headers.
  • Security Headers – Dedicated for header management.
  • HTTP Headers – Lets you set various headers.

After activation, go to the plugin’s settings page, configure HSTS (with max-age and subdomains), set CSP and other headers, then test using tools like securityheaders.com or your browser’s developer tools.

Tips

  • You need HTTPS for HSTS. Check that your certificate is valid and your site redirects to HTTPS.
  • Start with a strict CSP, then add exceptions as you identify needed external resources.
  • Test changes carefully to avoid breaking your site.

If this is a server level configuration, how can a plugin do this?

Plugins hook into WordPress just before headers go out. They use the send_headers action, then call PHP’s header() to add or change response headers.

Example

add_action( 'send_headers', 'add_security_headers' );
function add_security_headers() {
  header( 'Strict-Transport-Security: max-age=31536000; includeSubDomains; preload' );
  header( 'X-Frame-Options: SAMEORIGIN' );
}

Things to Watch

  • If the server already sets headers, a plugin may add duplicates or get overridden.
  • Plugins must run before any output is sent; otherwise header() fails.
  • Different plugins may conflict if they set the same header later in the process.

That said, server-level rules tend to be simpler, more reliable and a bit faster, since they don’t rely on PHP at runtime.

Need human WordPress help?

WP Assistant is a free tool created by Atiba Software, a WordPress design and development company located in Nashville, TN. If you need more personalized WordPress assistance let us know, and we’ll get back to you ASAP!