HOW TO SECURE VERCEL - SECURITY GUIDE | VIBEEVAL
Vercel Security Context
Vercel handles a lot of the platform layer — TLS, automatic HTTPS, basic DDoS scrubbing, edge networking. Your residual surface lives in: (1) what’s in the deployed bundle (env-var prefixes, accidentally-public secrets), (2) preview deployment URLs that bypass the auth gate on your custom domain, (3) serverless function configuration, and (4) headers / CORS / rewrites you control through vercel.json or next.config.js. The recurring incident shape is “preview URL works without auth, attacker finds it via the deployment list, all the auth-gated features are accessible.”
Security Checklist
1. Use the right env-var prefix per scope
Vercel exposes only NEXT_PUBLIC_* (Next.js) / VITE_* (Vite) / PUBLIC_* (Astro) to the browser. Everything else stays server-side. Audit your env vars in Project → Settings → Environment Variables — confirm secrets (Stripe key, OpenAI key, DB URL) do not have a public prefix. The bug ships when an AI tool suggests NEXT_PUBLIC_STRIPE_SECRET_KEY to “make it accessible from the page.”
2. Set per-environment values
Each env var has Production / Preview / Development scopes. Set distinct values per env — never share the production key with preview. Preview deploys can be reached by anyone with the URL; sharing prod keys with preview is a key leak waiting to happen.
3. Enable Deployment Protection on previews
Project → Settings → Deployment Protection (Pro plan): require Vercel auth, password, or shareable link to access preview / branch deploys. Without this, every git push creates a public URL — accessible to anyone who guesses or finds the URL — that has the full app, including all the routes you only meant production users to see.
4. Configure auth on every protected route
For Next.js App Router: auth() from @/auth at the top of every server action and route handler. For middleware-based gating: define matcher to cover every protected path, not just the obvious ones. Test by hitting /api/admin/foo from an incognito browser; should return 401.
5. Audit serverless function code
Each route in app/api/ and pages/api/ is internet-reachable. The first three lines of each handler must check the session. Add input validation (Zod) on the body. For long-running operations, set the function’s maxDuration explicitly so a malicious request can’t exhaust your monthly compute budget.
6. Enable Vercel Firewall
Project → Settings → Firewall: enable. Configure rate limits per route, IP allowlists for admin paths, and challenge rules for suspicious traffic. The Firewall sits in front of the function — it stops abusive traffic before it consumes function-execution time and your bill.
7. Configure security headers in vercel.json
{
"headers": [{
"source": "/(.*)",
"headers": [
{ "key": "Strict-Transport-Security", "value": "max-age=31536000; includeSubDomains; preload" },
{ "key": "X-Frame-Options", "value": "DENY" },
{ "key": "X-Content-Type-Options", "value": "nosniff" },
{ "key": "Referrer-Policy", "value": "strict-origin-when-cross-origin" },
{ "key": "Content-Security-Policy", "value": "default-src 'self'" }
]
}]
}
Verify with the Security Headers Checker.
8. Audit redirects and rewrites
In vercel.json redirects / rewrites: avoid open-redirect patterns like /r?to=... that obey the query parameter. Stick to specific source → specific destination. Open redirects are phishing pivots — see SSRF / open redirect / OAuth.
9. Verify HTTPS on every domain
Vercel handles HTTPS automatically. For custom domains, confirm the cert covers all variants (example.com, www.example.com, any subdomains in use). Test by hitting http://yourdomain.com and confirming the redirect to https://.
10. Configure rate limiting per route
Vercel Firewall does platform-level rate limiting; for application-level (per-user, per-action) use a Redis-backed counter (@upstash/ratelimit or equivalent). Tighten on /login, /signup, /reset-password, /api/expensive. The default is no limit, which means credential stuffing and bill-running attacks are free.
11. Review deployment logs
Project → Deployments → [deployment] → Logs: review weekly for: 5xx error spikes, repeated 4xx auth errors, requests to routes you don’t recognize. Vercel logs are short retention by default — stream to your SIEM if compliance requires longer.
12. Configure team permissions
Team → Settings → Members: review quarterly. Owner / Member / Developer / Viewer. Anyone with Developer access can deploy and read env vars — keep the list small. Ex-team members lose access on removal but their sessions persist; rotate sensitive secrets after departure.
13. Enable audit logs
Team → Settings → Audit Log (Pro+): track deployments, env-var changes, member additions, OAuth integrations. Useful for incident response.
14. Audit Edge Functions
Edge Functions run in V8 isolates with a smaller API surface than Node — but the same security rules apply: validate inputs, check auth, never include secrets in URL params (which end up in logs), set CORS to your origin only.
15. Configure DNS security
For custom domains: enable DNSSEC at your registrar. Add CAA records limiting cert issuance to Let’s Encrypt (or your CA of choice) — prevents an attacker who compromises another CA from issuing a valid cert for your domain.
16. Review third-party integrations
Team → Integrations: every integration has a token. Audit periodically — disconnect ones you stopped using. Each unused integration is a credential that could be compromised independently of your Vercel account.
17. Configure cache headers carefully
For pages that include user-specific data: Cache-Control: private, no-store to prevent accidental caching at edge. For public pages: explicit Cache-Control: public, max-age=... is fine. The bug shape is a logged-in page accidentally cached at the edge and served to other users.
18. Audit CORS on API routes
For routes called from your own frontend: don’t add CORS headers (same-origin works without). For cross-origin: allowlist the specific domain, never * with credentials. See CORS credentials misconfig.
19. Run a security scan
The Vibe Code Scanner catches the AI-specific deploy-side patterns Vercel hosts: source maps in production, exposed .env.example with real values, the preview-URL-bypass mentioned above. The full VibeEval scan adds BOLA and webhook trust.
Related Resources
Free Self-Audit Suite
Five free scanners.
Vibe Coding Security Risk Guide
Full risk catalogue.
Solo Founder Pre-Launch Checklist
12 checks before launch.
Automate Your Security Checks
VibeEval scans your Vercel deployment against every category above plus 305 more probes. Findings ship as paste-ready prompts for your AI editor.
SCAN YOUR APP
14-day trial. No card. Results in under 60 seconds.