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?
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.
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>
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=()";
max-age: Duration in seconds; 31536000 is one year.includeSubDomains: Applies to all subdomains.preload: Lets you add the site to browser preload lists.default-src 'self', but you may need to adjust for external resources.SAMEORIGIN).nosniff).strict-origin-when-cross-origin sends only the origin when crossing domains.geolocation=(), microphone=(), camera=() disables those features.Some plugins let you add headers without touching server files. Popular choices include:
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.
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.
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' );
}
header() fails.That said, server-level rules tend to be simpler, more reliable and a bit faster, since they don’t rely on PHP at runtime.
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!