Skip to content
>_ITDITDWeb Security Platform

By framework

Next.js security — Server Actions, environment variables, and dependency CVEs

Next.js incidents happen at the server/client boundary: env-var exposure (server-only secrets shipped to the client), missing authorization in Server Actions, and known dependency CVEs. Keep secrets server-only, scope by owner, monitor CVEs. Defensive, no attack steps.

Published 2026-07-02 Updated 2026-07-02 4 min read

For: anyone running a Next.js app. No attack steps here — just the incidents that happen at the server/client boundary and how to close them. For the full picture, see the security-by-framework hub.

The big three pitfalls (at the boundary)

Next.js's escaping and routing are excellent, but these three are yours to close by minding the boundary.

① Env-var exposure

Misused NEXT_PUBLIC_ or secrets passed to the client. Baked into the bundle, visible to visitors.

② Action authorization gaps

No owner check in Server Actions / Route Handlers. Swap an ID, operate on another user's data.

③ Known dependency CVEs

Core/dependency CVEs (incl. RCE) left unpatched. Judge by the running version, patch fast.

The three incidents most common in Next.js — all involve the server/client boundary.

How to close them (3 steps)

1

Keep secrets server-only

Prefix only browser-safe values with NEXT_PUBLIC_; never on API keys or connection info. Read secrets only inside server components / Server Actions / Route Handlers, and keep them out of props and responses. (→ .env files and secrets)
2

Authorize in every Server Action / Route Handler

These are public server entry points. On top of login (authentication), scope every operation to the user who owns the target. Forget it and an ID swap lets someone operate on another user's data (→ what IDOR is). Validate input in the action too.
3

Machine-monitor dependency CVEs and patch fast

Judge core/dependency vulnerabilities by the running version (package.json floors lie), detect early with machine monitoring, and patch fast. Most breaches start from an unpatched CVE being auto-exploited. (→ not falling behind on CVEs)

Common (dangerous)

  • secrets prefixed NEXT_PUBLIC_, exposed to the client
  • Server Actions treated as "logged in = allowed"
  • fetching external URLs on the server unguarded (SSRF)
  • known dependency CVEs left unpatched

Correct

  • secrets are server-only, never sent to the client
  • actions do owner-scoped authorization
  • URL fetches go through SSRF protection (block internal IPs, allowlist)
  • dependency CVEs machine-monitored + patched fast

This site's view: manage 'the boundary and dependencies,' not the core

This site runs on Next.js, and the center of gravity we actually guard isn't flashy config but the server/client boundary and dependency freshness. Secrets stay on the server, public entry points (Server Actions / Route Handlers) always carry authorization, and dependencies get a CVE audit before every deploy. Our own origin was an incident of "unpatched CVE auto-exploited," so machine-monitoring dependencies is a top-priority habit. Any code that fetches an external URL goes through our own SSRF-safe gateway so it can't reach internal IPs or metadata (→ what SSRF is).

FAQ

QIs Next.js a secure framework?
A

Next.js has safe defaults (output escaping, etc.) and is fairly solid out of the box. But incidents come not from the core defaults but from how you handle the server/client boundary: secrets that were meant to be server-only ending up in the client, forgetting authorization in Server Actions, and leaving known dependency CVEs unpatched. You can't rely on defaults alone — you manage the boundary and dependencies yourself.

QHow do I handle environment variables safely?
A

The rule is 'secrets stay on the server.' Only prefix values with NEXT_PUBLIC_ if they're safe for the browser; never on API keys or connection info (NEXT_PUBLIC_ values are baked into the client bundle at build time and visible to visitors). Read secrets only inside server components / Server Actions / Route Handlers, and design so they never slip into props or responses.

QWhat should I watch for with Server Actions?
A

Server Actions and Route Handlers are public server entry points. Being callable doesn't mean it's allowed. On top of login (authentication), write authorization that scopes every operation to the user who owns the target. Forget it and someone can update or delete another user's data just by swapping an ID (auth ≠ authz). Validate input, and always do the ownership check in the action.