Insecure Headers on Vercel
Vercel handles HTTPS, DDoS protection, and edge routing, but it does not inject application-level security headers into your responses. Without explicit configuration in next.config.js, vercel.json, or middleware, your Vercel deployment lacks Content-Security-Policy, X-Frame-Options, and other critical defenses.
Scan Your Vercel AppHow It Happens
Vercel's infrastructure provides TLS, HTTP/2, and basic bot protection at the edge. Developers see the padlock icon in the browser and assume their deployment is fully secured. But application-level security headers must be configured by the developer. Next.js does not set security headers by default. The most common Vercel deployment (a Next.js app) serves responses without Content-Security-Policy, X-Frame-Options, or Strict-Transport-Security unless the developer adds them in next.config.js or middleware.ts. Vercel supports headers in vercel.json for non-Next.js projects, but this configuration file is optional and rarely includes security headers in project templates. AI-generated projects deployed to Vercel almost never include header configuration because the AI focuses on application features, not deployment infrastructure.
Impact
Without Content-Security-Policy, any XSS vulnerability can load scripts from any domain, exfiltrate data to any server, and execute inline scripts without restriction. CSP is the most effective defense-in-depth against XSS exploitation. Missing X-Frame-Options allows clickjacking attacks where your Vercel deployment is embedded in a malicious iframe. Users think they are interacting with your site but are actually clicking hidden elements controlled by the attacker. Without Strict-Transport-Security (HSTS), users who type your domain without https:// are vulnerable during the HTTP-to-HTTPS redirect. A man-in-the-middle attacker can intercept this redirect and serve a malicious version of your site. HSTS tells the browser to always use HTTPS, eliminating this window.
How to Detect
Run curl -I https://your-app.vercel.app and examine the response headers. Look for the presence of Content-Security-Policy, X-Frame-Options, X-Content-Type-Options, Strict-Transport-Security, Referrer-Policy, and Permissions-Policy. In browser DevTools, the Network tab shows response headers for every request. Check the main document and API routes separately, as they may have different header configurations. Vibe App Scanner audits response headers on every scan and provides specific configuration guidance for Vercel and Next.js deployments, including ready-to-use header values.
How to Fix
For Next.js on Vercel, configure headers in next.config.js using the async headers() function. This is the recommended approach and works across all deployment platforms. For non-Next.js projects on Vercel, add headers in vercel.json under the headers key. This applies headers at the edge before your application code runs. For dynamic CSP with nonces, use Next.js middleware.ts to generate a unique nonce per request and inject it into both the CSP header and your script tags. Vercel's edge middleware runs before the page renders, making this approach efficient. Start with the safe defaults: X-Content-Type-Options: nosniff, X-Frame-Options: DENY, Strict-Transport-Security: max-age=63072000. Then add Content-Security-Policy and Permissions-Policy with testing to ensure they do not break your application.
Code Examples
Security headers for Vercel deployment
// vercel.json - no security headers
{
"buildCommand": "next build",
"framework": "nextjs"
}// vercel.json with security headers
{
"headers": [
{
"source": "/(.*)",
"headers": [
{ "key": "X-Content-Type-Options", "value": "nosniff" },
{ "key": "X-Frame-Options", "value": "DENY" },
{ "key": "Strict-Transport-Security",
"value": "max-age=63072000; includeSubDomains; preload" },
{ "key": "Referrer-Policy",
"value": "strict-origin-when-cross-origin" },
{ "key": "Permissions-Policy",
"value": "camera=(), microphone=(), geolocation=()" }
]
}
]
}Frequently Asked Questions
Does Vercel add any security headers automatically?
Vercel handles HTTPS and adds some infrastructure-level protections, but does not add application-level headers like CSP, X-Frame-Options, or HSTS. These must be configured by the developer in next.config.js, vercel.json, or middleware.
Should I use vercel.json or next.config.js for headers?
For Next.js projects, next.config.js is preferred because it stays with your application code and works on any deployment platform. Use vercel.json only for non-Next.js projects or when you need edge-level header configuration.
Will HSTS preload work on *.vercel.app domains?
HSTS works on any HTTPS domain including vercel.app subdomains. However, HSTS preload list submission requires owning the domain, so it only applies to custom domains. For vercel.app subdomains, HSTS still protects returning visitors.
Related Security Resources
Is Your App Vulnerable?
VAS automatically scans for insecure headers and other security issues in Vercel apps. Get actionable results with step-by-step fixes.
Scans from $5, results in minutes.