How to add security headers on any stack
Five headers cover most of the basics. Here’s what each one does and the exact lines for your server.
The starter set
Strict-Transport-Security: always use HTTPS for this site (see the HSTS guide before you enable it).X-Content-Type-Options: nosniff: stops browsers guessing file types.X-Frame-Options: SAMEORIGIN: stops other sites framing yours (clickjacking).Referrer-Policy: strict-origin-when-cross-origin: sends less of your URLs to other sites.Permissions-Policy: switches off browser features you don’t use.
nginx
Add inside your server { } block, then run nginx -t and reload.
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
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;Watch out: if a location block has its own add_header, nginx drops the server-level ones for that location. Repeat the headers there, or put them in a shared include file.
Apache (.htaccess)
Needs mod_headers (enabled on most hosts).
<IfModule mod_headers.c>
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"
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=()"
</IfModule>Cloudflare
- Turn on HSTS under SSL/TLS → Edge Certificates → HTTP Strict Transport Security.
- For the other headers, create a Response Header Transform Rule (Rules → Transform Rules → Modify Response Header) that sets each header as a static value for all incoming requests.
WordPress without server access
Create wp-content/mu-plugins/security-headers.php. Must-use plugins load automatically.
<?php
// Security headers for pages WordPress serves.
add_action( 'send_headers', function () {
header( 'X-Content-Type-Options: nosniff' );
header( 'X-Frame-Options: SAMEORIGIN' );
header( 'Referrer-Policy: strict-origin-when-cross-origin' );
header( 'Permissions-Policy: camera=(), microphone=(), geolocation=()' );
} );This only covers pages generated by PHP. Static files and some page caches bypass it, so server or CDN headers are better when you can use them.
Next: Content-Security-Policy
CSP is the most powerful header and the one most likely to break something. Follow the CSP guide and start in report-only mode.