Authentication, Authorization and Security
Every entry point in a Next.js app (pages, layouts, Server Actions, Route Handlers and Proxy) is reachable on its own, so authorization belongs next to the data, and only minimal, safe data should cross to the client.
Key points
- 1
Server Actions and Route Handlers are public endpoints: authenticate, authorize the specific resource (to prevent IDOR) and validate input inside each one, even if the page that shows the form already checked.
- 2
Proxy checks are optimistic, reading the cookie only. Layout checks do not re-run on client navigation and do not stop nested segments or parallel slots from rendering. Do the secure checks in a server-only Data Access Layer.
- 3
Props to Client Components and Server Action return values are serialized to the browser. Return small DTOs, keep client prop types narrow, and treat React taint APIs as a backup only.
- 4
Cookies can be read in Server Components but only set or deleted in Server Functions and Route Handlers. Use httpOnly, secure, sameSite, an expiry and a minimal payload.
- 5
Nonce-based CSP via Proxy requires dynamic rendering, so no static, ISR or PPR. Next.js attaches the nonce to its own scripts automatically, and experimental SRI is the static-friendly alternative.
- 6
Server Actions only accept POST, compare Origin with Host or X-Forwarded-Host (configure allowedOrigins behind proxies), cap bodies at 1MB, and encrypt closed-over variables. Set NEXT_SERVER_ACTIONS_ENCRYPTION_KEY when running several instances.
- 7
Never mark personalized responses as publicly cacheable, and keep per-user data out of shared caches: resolve the user inside an exported getter and pass only the ID into an unexported "use cache" function, or use "use cache: private".
Common traps
A redirect guard of next.startsWith("/") still allows //evil.example. React blocks javascript: URLs in href, but router.push still executes them.
JSON.stringify does not escape < inside dangerouslySetInnerHTML, so escape it as \u003c in JSON-LD scripts.
remotePatterns redirects are not re-validated. A hostname of "**" (with other fields omitted) turns the image optimizer into an open proxy.
Read the source
Test yourself on Authentication, Authorization and Security
Ten questions, with the answer and explanation after each one.