Free check
Security headers check
Security headers tell browsers how to protect your visitors: stay on HTTPS, refuse to be framed by other sites, and only run scripts you trust. They take minutes to add and close off whole classes of attack.
Why it matters
Without a Content-Security-Policy, one injected script can do anything on your pages. Without HSTS, a visitor's first request can be quietly downgraded to unencrypted HTTP. Without framing protection, another site can load yours invisibly and trick people into clicking (clickjacking).
These headers are set once in your hosting configuration and apply to every page, which makes them one of the cheapest security improvements you can make.
What this check looks at
- Strict-Transport-Security (HSTS), and whether its max-age is at least six months
- Content-Security-Policy, and whether it allows unsafe inline or wildcard scripts
- X-Frame-Options or CSP frame-ancestors (clickjacking protection)
- X-Content-Type-Options, Referrer-Policy and Permissions-Policy
- Server and X-Powered-By headers that reveal software versions
How to fix it
The Content-Security-Policy above is a strict starting point and will block inline scripts and third-party resources. Ship it as Content-Security-Policy-Report-Only first, see what it would block, then add the sources you need.
Vercel (vercel.json)
{
"headers": [
{
"source": "/(.*)",
"headers": [
{ "key": "Strict-Transport-Security", "value": "max-age=31536000; includeSubDomains" },
{ "key": "Content-Security-Policy", "value": "default-src 'self'; frame-ancestors 'none'; object-src 'none'; base-uri 'self'" },
{ "key": "X-Frame-Options", "value": "DENY" },
{ "key": "X-Content-Type-Options", "value": "nosniff" },
{ "key": "Referrer-Policy", "value": "strict-origin-when-cross-origin" },
{ "key": "Permissions-Policy", "value": "camera=(), microphone=(), geolocation=()" }
]
}
]
}
Netlify and Cloudflare Pages (_headers file)
/*
Strict-Transport-Security: max-age=31536000; includeSubDomains
Content-Security-Policy: default-src 'self'; frame-ancestors 'none'; object-src 'none'; base-uri 'self'
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
Referrer-Policy: strict-origin-when-cross-origin
Permissions-Policy: camera=(), microphone=(), geolocation=()
Nginx
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
add_header Content-Security-Policy "default-src 'self'; frame-ancestors 'none'; object-src 'none'; base-uri 'self'" always;
add_header X-Frame-Options "DENY" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always;
server_tokens off;
Apache (.htaccess)
<IfModule mod_headers.c>
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"
Header always set Content-Security-Policy "default-src 'self'; frame-ancestors 'none'; object-src 'none'; base-uri 'self'"
Header always set X-Frame-Options "DENY"
Header always set X-Content-Type-Options "nosniff"
Header always set Referrer-Policy "strict-origin-when-cross-origin"
Header always set Permissions-Policy "camera=(), microphone=(), geolocation=()"
</IfModule>
Next.js (next.config.js)
module.exports = {
async headers() {
return [
{
source: "/(.*)",
headers: [
{ key: "Strict-Transport-Security", value: "max-age=31536000; includeSubDomains" },
{ key: "Content-Security-Policy", value: "default-src 'self'; frame-ancestors 'none'; object-src 'none'; base-uri 'self'" },
{ key: "X-Frame-Options", value: "DENY" },
{ key: "X-Content-Type-Options", value: "nosniff" },
{ key: "Referrer-Policy", value: "strict-origin-when-cross-origin" },
{ key: "Permissions-Policy", value: "camera=(), microphone=(), geolocation=()" },
],
},
];
},
};
Express (helmet)
npm install helmet
# then in your app:
# import helmet from "helmet";
# app.use(helmet());
# app.disable("x-powered-by");
Questions
Which security header matters most?
Content-Security-Policy gives the most protection because it limits which scripts can run, but it takes the most care to set up. HSTS and X-Frame-Options are quick wins you can add in minutes.
Will adding a CSP break my site?
It can, if it blocks scripts or styles your pages rely on. Deploy it as Content-Security-Policy-Report-Only first, check the browser console for what would be blocked, and adjust before enforcing it.
Do I still need X-Frame-Options if I have frame-ancestors?
Modern browsers use CSP frame-ancestors and ignore X-Frame-Options when both are present. Keeping X-Frame-Options as well protects older browsers and costs nothing.