The basic security holes in a Next.js app
Most holes I find in audits aren't sophisticated: they're oversights. Here are the five most common gaps in a Next.js app, and the fix for each — before someone finds them for you.
Most holes I find in audits aren't sophisticated: they're oversights. Here are the five most common gaps in a Next.js app, and the fix for each — before someone finds them for you.
A key in a NEXT_PUBLIC_ variable ends up in the client bundle, readable by anyone.
An API route with no session check: anyone calls the endpoint directly.
You check the user is logged in, but not that the resource is theirs. They change the id and read someone else’s data.
dangerouslySetInnerHTML on unsanitized user content = script injection.
In Next.js, the client/server boundary is easy to cross by accident. The reflex: mark sensitive modules server-only, and remember that anything NEXT_PUBLIC_ is public by definition.
Where to store and inject secrets properly is the whole of handling secrets properly.
The most frequent and most serious mistake: checking who the user is, but not what they’re allowed to touch. Every route that reads or modifies a resource must verify the resource belongs to the user.
Never trust an id coming from the client. Always verify ownership server-side — it’s the number-one SaaS vulnerability.
Two of these have their own article: authentication in a Next.js app and rate limiting and API protection.
Basic security isn't an expert topic: it's a checklist. Server-side secrets, every route authorizing as much as authenticating, validated inputs, hardened cookies. Make it a systematic pass before every release, and you eliminate 90% of real vulnerabilities.
OWASP Top 10 ↗