Guide · 3 min read

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.

Updated · HackGrade

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.

nginx
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).

.htaccess
<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

  1. Turn on HSTS under SSL/TLS → Edge Certificates → HTTP Strict Transport Security.
  2. 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
<?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.

Sources

Related guides

Free · Instant · No sign-up

Find out your grade before someone else does.

Passive scan. Nothing is attacked without your permission.

Free to start. Paid plans from $12 a month, or a one-time report for $29. See pricing

This page is in English. Translations are on the way.