Next.js · security headers · hardening
Missing Security Headers in Next.js
Vercel and Next.js do not add security headers by default. Your app ships with an F on securityheaders.com and you only find out when a security audit or a paying customer asks. Paste your URL — we check HSTS, CSP, X-Frame-Options, and three more, then stamp CLEARED / HOLD / DENIED.
Headers Next.js apps typically miss
These are absent from a default Next.js + Vercel deployment.
No Strict-Transport-Security (HSTS)
Browsers may still use HTTP on revisits. Critical for apps with login or payment — session cookies leak on the HTTP hop.
No X-Frame-Options / frame-ancestors
Your app can be embedded in an iframe on a malicious site. Clickjacking targets auth flows and payment buttons.
No X-Content-Type-Options: nosniff
Browsers guess MIME types on user-uploaded files. A mismatch opens XSS vectors on CDN edges.
No Content-Security-Policy
Third-party scripts (analytics, chat widgets) can load anything. CSP is the header auditors ask for first.
No Referrer-Policy / Permissions-Policy
Full URLs leak to third-party origins. Camera, microphone, and geolocation defaults stay wide open.
next.config.js — all headers at once
One config block covers every header we check. Copy and adjust.
next.config.js — complete headers
/** @type {import('next').NextConfig} */
const nextConfig = {
async headers() {
return [
{
source: '/(.*)',
headers: [
{
key: 'Strict-Transport-Security',
value: 'max-age=31536000; includeSubDomains; preload',
},
{
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=()',
},
],
},
]
},
}
module.exports = nextConfigCSP starter — tighten after measuring
// Add to the headers array above:
{
key: 'Content-Security-Policy',
value: "default-src 'self'; img-src 'self' data: https:; script-src 'self'; style-src 'self' 'unsafe-inline'",
}
// ⚠️ CSP breaks things if too strict.
// 1. Deploy with Content-Security-Policy-Report-Only first
// 2. Check browser console for violation reports
// 3. Tighten, then switch to the real headerStill check by hand
- □Deploy and re-scan — headers appear only in production, not in next dev
- □If using a CDN (Cloudflare, etc.), set headers at the edge to avoid duplicates
- □Start with Content-Security-Policy-Report-Only before enforcing a real CSP
- □Test iframe embedding after adding X-Frame-Options: DENY — break intentional embeds?
Related
- Security headers checker — scan your site now
- Next.js production checklist
- SSL / HTTPS checker — HSTS pairs with HTTPS
- Methodology
- Go-Live Clearance home