Website Security Headers: A Complete Guide for 2026
A practical guide to the most important HTTP security headers — what they do, recommended values, and how to add them to your site to prevent XSS, clickjacking, and data leakage.
Security headers are HTTP response headers that instruct browsers on how to behave when handling your site's content. They're one of the fastest ways to harden a website: a few lines of server config that close entire classes of attacks — cross-site scripting, clickjacking, MIME sniffing, and data leakage.
This guide covers every header worth implementing in 2026, with recommended values and the reasoning behind them.
Why headers matter
Most web attacks don't exploit novel zero-days — they exploit predictable browser behaviours. Security headers change those defaults. A browser that knows your site should only load scripts from your own domain will refuse to execute an injected third-party script, even if your server was compromised enough to serve it.
Adding the right headers takes 30 minutes. Not adding them leaves your users exposed to attacks that have existed for 20 years.
The essential headers
1. Strict-Transport-Security (HSTS)
Forces browsers to only connect to your site over HTTPS, even if the user types http://. Eliminates protocol-downgrade and SSL-stripping attacks.
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
max-age=31536000— remember this policy for 1 yearincludeSubDomains— apply to all subdomainspreload— opt into browser preload lists (hardcoded HTTPS before the first request)
Before adding preload: ensure every subdomain serves HTTPS. Once on the preload list, HTTP access is permanently unavailable until removed (which takes weeks).
See also: HSTS
2. Content-Security-Policy (CSP)
The most powerful — and most complex — security header. CSP defines an allowlist of sources for scripts, styles, images, fonts, and more. Any resource not on the list is blocked by the browser.
Content-Security-Policy:
default-src 'self';
script-src 'self' https://cdn.posthog.com;
style-src 'self' 'unsafe-inline';
img-src 'self' data: https:;
font-src 'self';
connect-src 'self' https://api.posthog.com;
frame-ancestors 'none';
base-uri 'self';
form-action 'self'
Start with report-only mode:
Content-Security-Policy-Report-Only: default-src 'self'; report-uri /csp-report
This logs violations without blocking anything, so you can tune your policy before enforcing it.
Key directives:
default-src 'self'— baseline: only load from your own originscript-src— controls JavaScript sources; avoid'unsafe-inline'and'unsafe-eval'frame-ancestors 'none'— replaces X-Frame-Options; prevents your page being embeddedbase-uri 'self'— prevents base-tag injection attacksform-action 'self'— prevents forms posting to attacker-controlled URLs
3. X-Content-Type-Options
Prevents browsers from MIME-sniffing a response away from the declared content type. Stops an uploaded .txt file from being executed as JavaScript.
X-Content-Type-Options: nosniff
No configuration needed. Just add it. There's no reason not to.
4. X-Frame-Options
Prevents your page from being embedded in an <iframe>, protecting against clickjacking attacks where an attacker overlays an invisible copy of your page to steal clicks.
X-Frame-Options: DENY
Or use SAMEORIGIN if you need to embed your own pages in iframes. Note: if you implement CSP with frame-ancestors, that takes precedence in modern browsers and is more flexible — but X-Frame-Options still covers older browsers.
See also: Clickjacking
5. Referrer-Policy
Controls how much of the URL is shared in the Referer header when users navigate away from your site. URLs can contain sensitive data — session tokens, user IDs, search terms.
Referrer-Policy: strict-origin-when-cross-origin
This sends the full URL for same-origin requests (useful for analytics) but only the origin (https://yourdomain.com) for cross-origin requests.
See also: Referrer Policy
6. Permissions-Policy
Restricts which browser APIs are available to the page and embedded iframes. Prevents third-party scripts from silently accessing the camera, microphone, or geolocation.
Permissions-Policy: camera=(), microphone=(), geolocation=(), payment=(self)
The empty () syntax disables the feature entirely. List only the features your site actively uses.
See also: Permissions Policy
7. Cross-Origin headers (COOP, COEP, CORP)
This trio isolates your document from other origins at a deeper level, enabling features like SharedArrayBuffer and protecting against Spectre-class side-channel attacks.
Cross-Origin-Opener-Policy: same-origin
Cross-Origin-Embedder-Policy: require-corp
Cross-Origin-Resource-Policy: same-origin
Warning: COEP (require-corp) is strict — any cross-origin resource that doesn't include a Cross-Origin-Resource-Policy header will be blocked. Test thoroughly in staging first.
Quick implementation by platform
Vercel (vercel.json)
{
"headers": [
{
"source": "/(.*)",
"headers": [
{ "key": "Strict-Transport-Security", "value": "max-age=31536000; includeSubDomains" },
{ "key": "X-Content-Type-Options", "value": "nosniff" },
{ "key": "X-Frame-Options", "value": "DENY" },
{ "key": "Referrer-Policy", "value": "strict-origin-when-cross-origin" },
{ "key": "Permissions-Policy", "value": "camera=(), microphone=(), geolocation=()" }
]
}
]
}
Nginx
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-Frame-Options "DENY" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always;
Nuxt 3 (nuxt.config.ts)
routeRules: {
'/**': {
headers: {
'X-Content-Type-Options': 'nosniff',
'X-Frame-Options': 'DENY',
'Referrer-Policy': 'strict-origin-when-cross-origin',
}
}
}
Security headers grading checklist
[ ] Strict-Transport-Security present with max-age >= 1 year
[ ] X-Content-Type-Options: nosniff
[ ] X-Frame-Options: DENY or SAMEORIGIN (or CSP frame-ancestors)
[ ] Referrer-Policy set (not unsafe-url)
[ ] Permissions-Policy restricts unused features
[ ] Content-Security-Policy in place (or at least Report-Only)
[ ] No Server or X-Powered-By headers leaking version info
Check your headers with Sitecheck
Sitecheck's security scanner checks all of the above headers automatically and grades each one — free, no login required. Run a scan on your homepage to see exactly which headers are missing and what values are recommended.
Summary table
| Header | Protects against | Complexity |
|---|---|---|
| HSTS | Protocol downgrade, SSL stripping | Low |
| X-Content-Type-Options | MIME sniffing | Low |
| X-Frame-Options | Clickjacking | Low |
| Referrer-Policy | Data leakage via Referer | Low |
| Permissions-Policy | Feature abuse by third-party scripts | Medium |
| CSP | XSS, injection, resource hijacking | High |
| COOP/COEP/CORP | Spectre-class side-channel attacks | High |
Start with the low-complexity headers today. Add CSP in report-only mode, tune it over a week, then enforce it. The full stack takes an afternoon and protects your users indefinitely.