How to Secure Your Vercel App
Last updated: January 12, 2026
Vercel's deep Next.js integration means security decisions happen in framework-specific ways. The NEXT_PUBLIC_ prefix silently exposes variables to browsers, Server Actions are callable by anyone, and Edge Middleware creates a new security boundary. This guide covers the Vercel-specific configuration that matters.
Why Security Matters for Vercel
Key Security Concerns
Security Strengths
Step-by-Step Security Guide
1. Audit NEXT_PUBLIC_ Variables
The NEXT_PUBLIC_ prefix embeds variables into client-side JavaScript at build time. Search your .env files for any secrets using this prefix — they're visible to every user.
# DANGEROUS — embedded in client bundle:
NEXT_PUBLIC_STRIPE_SECRET=sk_live_abc123
# SAFE — server-side only:
STRIPE_SECRET=sk_live_abc123
NEXT_PUBLIC_STRIPE_PUBLISHABLE=pk_live_abc1232. Secure Server Actions
Server Actions are exposed as POST endpoints that anyone can call directly — the UI button is not a security boundary. Add auth and authorization checks inside every Server Action.
// Every Server Action needs this pattern:
'use server'
async function deleteAccount(formData: FormData) {
const session = await getServerSession();
if (!session) throw new Error('Unauthorized');
// Verify ownership before acting
const userId = session.user.id;
await db.delete(accounts).where(eq(accounts.userId, userId));
}3. Add Security Headers via Next.js Config
Add CSP, HSTS, and other security headers through the Next.js headers() function — this is the Vercel-native way to configure them.
// next.config.js
headers: async () => [
{
source: '/(.*)',
headers: [
{ key: 'X-Frame-Options', value: 'DENY' },
{ key: 'X-Content-Type-Options', value: 'nosniff' },
{ key: 'Strict-Transport-Security', value: 'max-age=31536000; includeSubDomains' },
],
},
]4. Scope Environment Variables per Environment
Vercel lets you set different values for Production, Preview, and Development. Without scoping, preview deployments use production API keys — meaning any PR can trigger production actions.
5. Enable Deployment Protection
Every git push generates a public preview URL. Enable Deployment Protection to require Vercel authentication, password, or trusted IPs before accessing previews.
6. Use Edge Middleware for Auth and Scan
Add middleware.ts to enforce authentication before requests reach your pages. Then run VAS on the deployed site to catch exposed secrets and header gaps.
// middleware.ts
import { NextResponse } from 'next/server';
export function middleware(request) {
const token = request.cookies.get('session');
if (!token && request.nextUrl.pathname.startsWith('/dashboard')) {
return NextResponse.redirect(new URL('/login', request.url));
}
}Common Security Mistakes
Avoid these common Vercel security pitfalls:
Known Vercel Vulnerabilities
These are documented security issues specific to Vercel applications. Click through for detailed remediation guidance.
Recommended Security Tools
Use these tools to maintain security throughout development:
Ready to Secure Your App?
Security is an ongoing process, not a one-time checklist. After implementing these steps, use VAS to verify your Vercel app is secure before launch, and consider regular scans as you add new features.
Frequently Asked Questions
Are Vercel environment variables secure?
Yes, Vercel encrypts them at rest and in transit. The risk is NEXT_PUBLIC_ — it embeds the value in your client JavaScript bundle at build time. Only use NEXT_PUBLIC_ for truly public values like API URLs.
Do Server Actions need auth checks?
Yes, always. Server Actions are exposed as POST endpoints. Anyone can call them with fetch or curl, bypassing the UI entirely. Add getServerSession() or equivalent at the start of every Server Action.