Security Headers
Add HTTP security headers to block common attacks with a five-minute server config change.
What this covers: Add HTTP security headers to block common attacks with a five-minute server config change, including does this apply to you?, implementation priority.
Who it’s for: WordPress site owners and administrators who need to secure their site against common threats.
Key outcome: You’ll have content-security-policy header is active and blocks inline scripts not in your allowlist, and strict-transport-security (hsts) header is set with a max-age of at least 31536000 (one year).
Time to read: 6 minutes
Part of: Security + Infrastructure series
Copy-paste these security headers into your server config. Done in 5 minutes.
Does This Apply to You?
If your site is publicly accessible on the internet, yes. Security headers protect every visitor, not just logged-in users. They’re especially critical if:
- You accept any user input — forms, comments, search boxes, file uploads. These are XSS and injection vectors that CSP mitigates.
- You handle payments or personal data — HSTS and secure headers are baseline requirements for PCI-DSS and GDPR compliance.
- You embed third-party scripts — analytics, chat widgets, ad pixels. Each one is a supply-chain attack surface that CSP constrains.
A site with zero headers gets an F grade on securityheaders.com. Most hosting providers ship with zero headers by default. The gap between “no headers” and “B grade” takes five minutes to close. The gap between B and A+ takes an afternoon (CSP is the hard part).
Implementation Priority
Not all headers carry equal weight. Implement them in this order based on risk reduction per effort:
| Priority | Header | Effort | Risk it mitigates |
|---|---|---|---|
| 1 | Strict-Transport-Security (HSTS) | 1 minute | SSL stripping, man-in-the-middle attacks |
| 2 | X-Content-Type-Options | 1 minute | MIME sniffing attacks |
| 3 | X-Frame-Options | 1 minute | Clickjacking |
| 4 | Referrer-Policy | 1 minute | URL data leakage to third parties |
| 5 | Permissions-Policy | 1 minute | Unauthorized device access (camera, mic) |
| 6 | Content-Security-Policy | 1-4 hours | XSS, code injection, data exfiltration |
Headers 1-5 are safe to deploy immediately with near-zero breakage risk. CSP requires testing.
The Headers You Need
Add these to your .htaccess (Apache) or nginx.conf:
Apache (.htaccess)
Header set X-Content-Type-Options "nosniff"
Header set X-Frame-Options "SAMEORIGIN"
Header set X-XSS-Protection "1; mode=block"
Header set Referrer-Policy "strict-origin-when-cross-origin"
Header set Permissions-Policy "geolocation=(), microphone=(), camera=()"
Nginx
add_header X-Content-Type-Options "nosniff" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Permissions-Policy "geolocation=(), microphone=(), camera=()" always;
WordPress (via plugin)
If you can’t edit server config, use HTTP Headers or Headers Security Advanced & HSTS WP plugins.
Add HSTS (Do This Carefully)
HSTS tells browsers to always use HTTPS, even if someone types http://. It’s the single highest-impact security header, but it has a gotcha: once a browser sees an HSTS header, it will refuse to load your site over HTTP for the duration of max-age. If your SSL certificate expires or you need to revert to HTTP, visitors are locked out.
Start with a short max-age and increase it over 2-4 weeks:
# Week 1: 5 minutes (test)
Header set Strict-Transport-Security "max-age=300"
# Week 2: 1 week
Header set Strict-Transport-Security "max-age=604800"
# Week 3+: 1 year (production)
Header set Strict-Transport-Security "max-age=31536000; includeSubDomains"
Only add includeSubDomains if every subdomain supports HTTPS. One forgotten staging subdomain on HTTP will become inaccessible. Never add the preload directive unless you fully understand it — preloading is essentially permanent and requires submission to a browser-maintained list.
Test Your Headers
Go to securityheaders.com and enter your URL. You want at least a B grade.
Content Security Policy (Advanced)
CSP is powerful but can break things. Start with report-only mode:
Header set Content-Security-Policy-Report-Only "default-src 'self'; script-src 'self' 'unsafe-inline' https://www.googletagmanager.com; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:;"
Watch the browser console for CSP violations. Fix them, then switch to enforcing mode (remove -Report-Only).
Common gotcha: if you use Google Tag Manager, Google Analytics, a chat widget, and a payment processor, your CSP will need to whitelist 8-15 domains. Each third-party script you add weakens the policy. This is a real trade-off — every marketing tool you embed expands your attack surface. Document every domain in your CSP and review quarterly.
What Each Header Does
- X-Content-Type-Options: Prevents MIME-type sniffing attacks
- X-Frame-Options: Blocks clickjacking (your site in hidden iframes)
- X-XSS-Protection: Enables browser XSS filtering
- Referrer-Policy: Controls what URL info is sent to other sites
- Permissions-Policy: Restricts access to browser features (camera, location)
- Content-Security-Policy: Controls where resources can load from
Note on X-XSS-Protection: this header is deprecated in modern browsers (Chrome removed its XSS auditor in 2019). Include it for older browser coverage, but do not rely on it — CSP is the real protection against XSS.
Checking Your Security Grade
- securityheaders.com shows B grade or better
- Site loads normally (no broken scripts or styles)
- Browser console shows no unexpected errors
Sources
- HTTP Headers
- Headers Security Advanced & HSTS WP
- submission to a browser-maintained list
- securityheaders.com
Security Headers Questions Answered
What are the most important security headers to implement?
The five essential security headers are: Content-Security-Policy (prevents XSS attacks), Strict-Transport-Security (forces HTTPS), X-Content-Type-Options (prevents MIME sniffing), X-Frame-Options or frame-ancestors CSP (prevents clickjacking), and Referrer-Policy (controls information sent in referrer headers). Implementing all five covers the most common web attack vectors.
What is Content-Security-Policy and why is it important?
Content-Security-Policy (CSP) tells browsers which sources of content (scripts, styles, images, fonts) are allowed to load on your page. It is the single most effective header against cross-site scripting (XSS) attacks because it blocks inline scripts and unauthorized external scripts from executing, even if an attacker injects malicious code into your page.
How do you test your security headers?
Use securityheaders.com to scan your site and get a letter grade (A+ through F) with specific recommendations. Mozilla’s Observatory (observatory.mozilla.org) provides a more detailed analysis. Test in staging first, as overly restrictive headers (especially CSP) can break legitimate site functionality like inline scripts and third-party embeds.
Will security headers break my website?
Strict-Transport-Security, X-Content-Type-Options, and X-Frame-Options rarely cause issues. Content-Security-Policy is the most likely to break functionality because it blocks inline scripts, inline styles, and third-party resources not explicitly whitelisted. Start with CSP in report-only mode (Content-Security-Policy-Report-Only) to identify violations before enforcing.
✓ Your HTTP Security Headers Are Properly Configured
- Content-Security-Policy header is active and blocks inline scripts not in your allowlist
- Strict-Transport-Security (HSTS) header is set with a max-age of at least 31536000 (one year)
- X-Content-Type-Options is set to “nosniff” on all responses
- X-Frame-Options or CSP frame-ancestors prevents your site from being embedded in unauthorized iframes
- SecurityHeaders.com scan returns an A or A+ grade
Test it: Visit securityheaders.com, enter your domain, and confirm you receive at minimum an A grade with no missing critical headers flagged in red.