Fix cards for TypeScript and Next.js

A01:2025 Broken Access Control

  • Missing object-level authorization (IDOR and BOLA)CWE-862 · CWE-639 · CWE-863

    Get the user from your authentication inside each route handler and server action, never from the request, and put one scope in every invoice query: tenant_id = $tenant AND (owner_id = $user OR $isBillingAdmin).

  • Open redirectCWE-601

    Resolve next against your own origin with new URL(next, site), the WHATWG parser browsers use, and pass the result to redirect() only if url.origin is in an exact allowlist and the URL has no user name or password; otherwise redirect to a fixed page.

  • Path traversalCWE-22 · CWE-23 · CWE-36 · CWE-59

    Check where the path lands, not what it looks like: resolve base with fs.realpath, resolve the request with realpath(path.resolve(base, name)), which collapses ../ and follows symlinks, and serve it only if it starts with base + path.sep.

  • Server-side request forgery (SSRF)CWE-918

    Attach the policy to the connection, not the hostname string.

A05:2025 Injection

  • Cross-site scripting (XSS)CWE-79

    Render user text as React children and attributes, which React escapes, and keep it out of dangerouslySetInnerHTML; if a field must carry HTML, sanitize it with DOMPurify first.

  • OS command and argument injectionCWE-78 · CWE-88

    Run the program directly with its arguments as a list, execFileSync(tool, ['--', name]), so no shell parses them, and put '--' before any user operand so a leading dash cannot pose as an option.

  • SQL injectionCWE-89

    Bind every value: put ? placeholders in the SQL and pass the values to the driver, as in db.prepare(sql).all(name, status), inside the route handler's data layer.

A06:2025 Insecure Design

  • ClickjackingCWE-1021

    Send a framing policy on sensitive pages, in middleware so every matched response carries it.

  • Unrestricted file uploadCWE-434 · CWE-646 · CWE-73 · CWE-770

    Decide the type from the bytes, not from file.type or the name.

A07:2025 Authentication Failures

A08:2025 Software or Data Integrity Failures

  • Mass assignment (over-posting)CWE-915

    Never pass await request.json() or Object.fromEntries(formData) to Object.assign, a spread or an ORM create or update.

Not covered in Next.js yet

These weaknesses have fix cards in other stacks but not in this one.

Supported versions

The latest major is in Active LTS; the previous major gets critical and security fixes only, until two years after its first release. Next.js support policy.

Next.js
VersionLatestStatusReleasedEnd of support
16.x16.4.0SupportedActive LTS until 17.x ships; the cards use it.21 October 202521 October 2027
15.x15.5.27MaintenanceMaintenance LTS (critical and security fixes) for two years after its release, so until 2026-10-21; move to 16.x.21 October 202421 October 2026
14.x14.2.35End of life26 October 202326 October 2025
Node.js
VersionLatestStatusReleasedEnd of support
2626.11.1SupportedCurrent release until 2026-10-27; Active LTS from 2026-10-28 and Maintenance LTS from 2027-10-20 on the release schedule.5 May 202630 April 2029
2424.21.0SupportedActive LTS until 2026-10-19; Maintenance LTS from 2026-10-20 on the release schedule.6 May 202530 April 2028
2222.23.3MaintenanceMaintenance LTS since 2025-10-21.24 April 202430 April 2027

Next.js 16 requires Node.js 20.9 or later; run an Active or Maintenance LTS line, since Node.js 20 is past its end of life. Node.js release schedule

How the fix cards choose versions

Minimum secure versions

The lowest release in each supported line that fixes every published advisory listed here. Anything older is missing a security fix.

PackageAt leastWhy
next16.3.8Seven advisories fixed on 30 September 2026, such as SSRF in Image Optimization (CVE-2026-94483) and cache poisoning (CVE-2026-94484, CVE-2026-94543); earlier 2026 releases fixed proxy (middleware) bypasses and remote code execution. Advisory
next15.5.27CVE-2026-94484, CVE-2026-94543 and CVE-2026-94485 for 15.x, whose support ends on 2026-10-21; after that, only 16.x gets fixes. Advisory
node22.23.2, 24.18.1 or 26.5.1The 29 July 2026 security releases, the latest on 11 October 2026: an HTTP/2 use-after-free (CVE-2026-56848), a Permission Model bypass (CVE-2026-58043), HTTP/2 memory exhaustion in 22.x and 24.x (CVE-2026-56846) and eight lower-severity CVEs. Advisory

Middleware and security order

  1. Headers in next.config: Set security headers with headers() (or in proxy for a CSP nonce) and poweredByHeader: false.
  2. Proxy (formerly middleware): proxy.ts runs before routes on the paths its matcher selects. Use it for redirects and coarse checks, never as the only authorization: matchers can skip paths and server functions, and CVE-2025-29927 and the 2026 proxy bypasses showed it can be skipped.
  3. Route handlers and server actions: Authenticate and authorize inside each one, through a server-only data access layer; Next.js says an exported server action can be called with a direct POST.
  4. Server action origin check: Next.js rejects an action whose Origin host differs from the request's host; add experimental.serverActions.allowedOrigins only for proxies you run.
  5. Rendering: Server and client components render text through React's escaping; return only the fields the page needs.

Secure defaults and settings

SettingValueWhy
poweredByHeadertrue (sends X-Powered-By: Next.js)Set false.
serverActions.bodySizeLimit1 MBLower it where actions take small inputs.
Server action origin checkOn in development and productionKeep allowedOrigins to hosts you control.
NEXT_PUBLIC_ environment variablesInlined into the client bundleNever give a secret that prefix.

Escape hatches to search for

Framework APIs that switch a protection off. Each one is sometimes needed; search for them in review and make each use justify itself.

APIRiskInstead
dangerouslySetInnerHTMLInserts HTML without escaping.Render text, or sanitize first; escape < in JSON written into a script tag.
Authorization only in proxy.tsMatchers and bypasses leave routes and server functions open.Check in each route handler and action.
redirect() or NextResponse.redirect() with a URL from the requestOpen redirect; redirect() does not validate its argument.Resolve against your origin and compare with an allowlist.
experimental.serverActions.allowedOrigins with broad wildcardsWeakens the CSRF check for server actions.Name the exact hosts.
Prisma $queryRawUnsafe or Drizzle sql.raw()SQL injection.$queryRaw tagged templates or sql with placeholders.

Checklist, mapped to ASVS 5.0.0

  • v5.0.0-8.3.1 Authorization runs in server code (route handlers, actions, the data access layer), never only in proxy or the client.
  • v5.0.0-8.2.2 Each action and route handler checks the caller owns the object.
  • v5.0.0-3.2.2 User content renders as text through React, not through dangerouslySetInnerHTML.
  • v5.0.0-3.5.1 Server actions keep the origin check; cookie-authenticated route handlers that change state check Origin or a token.
  • v5.0.0-15.3.1 Server code returns only the fields the client needs.
  • v5.0.0-9.1.1 Bearer tokens are verified with jose (or similar) before any claim is read.
  • v5.0.0-13.4.6 poweredByHeader is off.
  • v5.0.0-15.2.1 Next.js is at or above the minimum secure version for its line.

References

  1. Next.js: data security guide
  2. Next.js: proxy.js file convention
  3. Next.js: serverActions configuration
  4. Next.js: poweredByHeader
  5. Next.js support policy
  6. GitHub advisory GHSA-f82v-jwr5-mffw (CVE-2025-29927, middleware authorization bypass)

All fix cards