Security checklist for Next.js apps built with Cursor or Claude Code
Last updated
Check authorization inside every route handler and server action, not only in middleware; keep secrets out of NEXT_PUBLIC_ variables; verify webhook signatures; read prices from your payment provider on the server; rate-limit AI endpoints and set provider spending caps; add security headers; and scan the deployed URL after each release.
Where AI-written Next.js code usually goes wrong
Agents are good at making features work and less careful about who may use them. The typical result is an API route or server action that returns or changes data without checking the session, or checks that a user is signed in but not that the record belongs to them.
Middleware alone is not an authorization layer. In March 2025 a Next.js vulnerability (CVE-2025-29927) let attackers skip middleware with a crafted header on unpatched versions. Keep checks next to the data access as well.
The checklist
- In every route handler and server action, load the session, return 401 when there is none, and scope every query to the signed-in user or organisation.
- Keep secret keys in server-only environment variables. Anything prefixed NEXT_PUBLIC_ is shipped to the browser.
- Verify webhook signatures (Stripe, Paddle, GitHub) using the raw request body before acting on an event.
- Create checkout sessions from price IDs stored on the server. Never accept an amount or plan from the request body.
- Put AI endpoints behind auth, rate-limit them per user, cap input size, and set a monthly budget in the AI provider’s dashboard.
- Add security headers: Content-Security-Policy, Strict-Transport-Security, X-Content-Type-Options and frame-ancestors.
- Keep Next.js and dependencies patched; run a dependency audit on every pull request.
- Ask your agent to review its own diff for missing auth checks (Claude Code has a /security-review command), then scan the deployed URL.
A prompt you can give your coding agent
List every route handler, server action and API route in this project. For each one, show whether it checks the session, whether it scopes the query to the current user or organisation, and whether it validates input with a schema. Fix any that do not, without changing behaviour for authorised users, and show me the diff.
Questions
- Is server-side rendering enough to keep data private?
- No. Server components can still render another user’s data if the query is not scoped, and route handlers are public URLs that anyone can call directly.
- What can a URL scan find in a Next.js app?
- Leaked keys in client bundles, public source maps, exposed .env or .git files, missing headers, open API docs, cookie flags and AI endpoints that answer without auth. Logic flaws need a code review or a test with real accounts.
Related Defexity checks
- SEC-016: Secret key exposed in public HTML or JavaScript
- SEC-015: JavaScript source maps are public
- SEC-021: AI endpoint shows no sign of auth or rate limiting
- SEC-005: Content-Security-Policy missing or permissive
- CODE-008: Server secret exposed through a public env prefix (code check, with GitHub)
- CODE-013: Stripe webhook without signature verification (code check, with GitHub)
Sources
Defexity reports potential risks it can see from outside your app. It is not a guarantee of security and not legal advice.