Next.js failure modes cluster around the server/client boundary and what runs with full privileges. The build passes either way — these don’t show up until someone hits the endpoint directly.
Critical
Secrets behind NEXT_PUBLIC_ — or imported into a client component
Anything prefixed NEXT_PUBLIC_ is inlined into the browser bundle. So is any env var imported, even transitively, into a "use client" component. A Stripe, database or API secret on that path is public the moment you deploy.
check › Grep for NEXT_PUBLIC_ on anything not meant to be public, and check what your client components import.
Critical
Route handlers and server actions with no auth check
An app/api/* route or a server action runs on the server with full privileges and is callable by anyone who knows the URL. Hiding the button in the UI does not protect it — each one needs its own authentication and authorization check.
check › Does every route handler and server action verify the session before doing work?
Critical
Auth enforced only in middleware.ts
Middleware matchers are easy to misconfigure, and matched paths can slip through. Auth that lives only in middleware leaves a single point of failure — it belongs at the data-access layer too.
check › If middleware is the only gate, one wrong matcher = an open route.
Watch
Server actions that trust their input
Server actions feel like local function calls but accept arbitrary client input. Without validation and an ownership check they become an injection or IDOR path — editing a record by passing someone else’s id.
check › Are action inputs validated, and is the acting user authorized for that record?
Watch
No rate limiting on route handlers
Auth, signup and any third-party-cost endpoint are open to brute force and runaway billing when nothing throttles them.
check › Is there rate limiting on auth and on any endpoint that costs money to call?
These are the patterns, not a checklist run against your repo. The audit reads your
actual Next.js code and tells you which of these are really there — prioritized,
critical first. Or try the free 2-minute self-check →