Next.js is one of the most popular frameworks for building full-stack web applications. But with great power comes great attack surface: API routes, server components, middleware, environment variables, and client-side rendering all introduce security considerations.
This guide shows you how to use Ship Safe to audit your Next.js app for vulnerabilities and fix them before they ship.
Quick Start
cd your-nextjs-app
npx ship-safe audit .Ship Safe automatically detects Next.js and adjusts its scanning accordingly.
1. Leaked Environment Variables
The most common Next.js security mistake: accidentally exposing secrets through NEXT_PUBLIC_ prefixed variables.
[SECRETS] API key exposed via NEXT_PUBLIC_ prefix
.env.local:5 → NEXT_PUBLIC_STRIPE_SECRET_KEY should not use NEXT_PUBLIC_ prefix
Severity: CRITICALThe rule: Only use NEXT_PUBLIC_ for values that are safe to expose in the browser. Never for API keys, database URLs, or auth secrets.
2. Unprotected API Routes
Next.js API routes (both pages/api/ and app/api/) without authentication or rate limiting.
[AUTH] API route without authentication check
app/api/users/route.ts:1 → Add auth middleware
OWASP: A07:2025 Authentication FailuresFix: Add auth checks and rate limiting to every state-changing route.
3. Server Actions Without Validation
Next.js Server Actions that accept user input without validation are vulnerable to injection and mass assignment attacks.
[INJECTION] Server Action processes unvalidated user input
app/actions.ts:15 → Validate input with Zod schema
OWASP: A03:2025 InjectionFix: Use Zod schemas to validate all Server Action inputs. Whitelist allowed fields.
4. XSS via dangerouslySetInnerHTML
React's escape hatch for rendering raw HTML is a common XSS vector.
Fix: Always sanitize with DOMPurify before rendering user-provided HTML.
5. Missing Security Headers
Next.js doesn't set security headers by default. Ship Safe checks your next.config.js and middleware for Content-Security-Policy, X-Frame-Options, and others.
Fix: Configure headers in next.config.js using the headers() function.
6. Supabase RLS Issues
If you use Supabase with Next.js, Ship Safe's dedicated SupabaseRLSAgent checks for Row Level Security misconfigurations and service_role key exposure in client-side code.
CI/CD Integration
name: Security Audit
on: [push, pull_request]
jobs:
ship-safe:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: asamassekou10/ship-safe@v6
with:
path: .
threshold: 70
github-pr: trueNext.js Security Checklist
After running npx ship-safe audit ., verify:
- No secrets in
NEXT_PUBLIC_variables - All API routes have authentication
- Rate limiting on auth endpoints
- Server Actions validate input with Zod
dangerouslySetInnerHTMLuses DOMPurify- Security headers configured in
next.config.js - Supabase RLS enabled (if applicable)
- Docker runs as non-root user
- Dependencies are up to date
- CI/CD pipeline includes security scanning
Ship fast. Ship safe.