Skip to content
OTFotf
All posts

Next.js Secures Framework with Nine Critical Patch Updates

D
DaveAuthor
7 min read
Next.js Secures Framework with Nine Critical Patch Updates

Why ship nine CVEs in one drop?

Vercel just published nine security advisories for Next.js and pushed a single coordinated patch — 15.5.21 for the 15.x line and 16.2.11 for 16.x. That's a quietly impressive amount of hygiene work for a framework this big. The issues include two SSRFs in request-routing features, a middleware/proxy bypass, a DoS path through Server Actions, two cache confusion bugs, and an Image Optimization crash that takes malicious SVG as input. All fixed in one release. The alternative — nine advisories discovering each other piecemeal over weeks — is the kind of thing that makes security teams pull their hair out. So: hats off to Vercel for the coordination and to researcher KarimPwnz for the reporting.

The reason this still matters to you, today, is that the advisory batch covers versions going back to 12.0.0. If you're on any Next.js between 12.x and 15.5.20, or between 16.0.0 and 16.2.10, you're exposed. The fix is one npm install away. The rest of this post is the upgrade ritual done right — and the two SSRF patterns worth understanding so you don't reintroduce them.

What's actually in the batch

Eight of the nine advisories are spelled out in the disclosure; the ninth rounds out the coordinated release. Here's the lineup as filed:

CVEGHSASeveritySurface
CVE-2026-64645GHSA-p9j2-gv94-2wf4HighSSRF via rewrites() / redirects()
CVE-2026-64649GHSA-89xv-2m56-2m9xHighSSRF via Server Actions on custom Node servers
CVE-2026-64642GHSA-6gpp-xcg3-4w24HighMiddleware + proxy bypass (Turbopack + legacy middleware.ts + single-locale i18n)
CVE-2026-64641GHSA-m99w-x7hq-7vfjHighDoS via malicious Server Actions
CVE-2026-64646GHSA-4c39-4ccg-62r3ModerateUnbounded Server Action payload in Edge runtime
CVE-2026-64644GHSA-q8wf-6r8g-63chModerateImage Optimization crash via malicious SVG
CVE-2026-64648GHSA-68g3-v927-f742ModerateCache confusion
CVE-2026-64647GHSA-4633-3j49-mh5qModerateCache confusion

severity split across the nine advisories — weighted toward high-impact issues

The four high-severity entries are what justify the rush: the two SSRFs coerce the Next.js server into hitting arbitrary hosts (including internal ones), the middleware bypass can skip authorization entirely on a specific config combo, and the DoS path is one malformed request away from memory pressure.

11 production screens. Login, database, payments — all wired.

The SaaS Dashboard Kit ships everything already connected. Nothing to set up. Live demo at saas.otf-kit.dev.

See the live demo

How bad does each class actually get?

SSRF in this context doesn't mean "someone reads your /etc/passwd." It means your Next.js server, acting on your behalf, can be tricked into issuing a request to an arbitrary hostname — including internal-only services with no public address. In the rewrites case, the destination hostname is built from attacker-controlled request data, so a crafted path or query string steers the outbound request. In the Server Actions case on custom Node servers, the same trick works against the outbound request an action performs. Both end up in post-mortems under "data exfiltration from internal service."

The middleware bypass — CVE-2026-64642 — is narrower but nastier: it requires Turbopack, a legacy middleware.ts, and single-locale i18n configured together. If that triple applies to your app, an attacker can skip authorization entirely. The DoS via Server Actions takes a single malformed request and turns it into memory pressure. The Image Optimization SVG path lets an attacker crash an endpoint by uploading hostile markup — lesser impact in isolation, but a great staging ground for a noisy attack.

The two cache confusion bugs round out the batch as a reminder: caching is security, not just performance. Their real teeth show up when you share cached responses across users.

How do you patch this today?

The work is straightforward. The discipline is doing it everywhere and not regressing.

# 15.x line
npm install next@15.5.21

# 16.x line
npm install next@16.2.11

# yarn
yarn add next@15.5.21
# or
yarn add next@16.2.11

# pnpm
pnpm update next@15.5.21
# or
pnpm update next@16.2.11

Then check what pulls in Next transitively and lock the floor. A pnpm why next or yarn why next will surface it; anywhere you still see 12.x through 15.5.20 or 16.0.0 through 16.2.10, that's still exposed. Vercel-hosted deployments get the new resolver automatically, but a self-hosted environment is on its own — a CI image rebuilt against the old floor is a quiet way to stay vulnerable after you thought you were safe.

Where do SSRFs sneak in, and how do you keep them out?

You can defend against the next SSRF before you upgrade, by refusing to build destination hostnames from user input. The rewrites/redirects SSRF happens when a rule like this exists:

// next.config.js — unsafe
async rewrites() {
  return [
    {
      source: '/proxy/:path*',
      destination: `
    },
  ]
}

The hostname in destination is reachable from a request header — the attacker controls the upstream you talk to. Replace it with a literal, allowlisted host:

// next.config.js — safe
async rewrites() {
  return [
    {
      source: '/proxy/:path*',
      destination: ' // literal, no interpolation
    },
  ]
}

The Server Actions variant on custom Node servers is the same shape: any outbound fetch inside an action should target a hardcoded or strictly allowlisted URL — never one derived from headers(), the request body, or searchParams. Treat "destination = f(user input)" as a code-review smell across rewrites, redirects, Server Actions, and middleware proxies.

Which framework settings shrink the next batch's blast radius?

Patching closes today's holes. The build settings below shrink the blast radius whenever the next batch ships — and Vercel has committed to a monthly security release cadence, so there will be more.

// next.config.js — security posture
module.exports = {
  // 1. Refuse SVG unless you render them yourself
  images: {
    dangerouslyAllowSVG: false,
    contentSecurityPolicy: "default-src 'self'; script-src 'none'; sandbox;",
  },

  // 2. Headers Vercel can't infer from context
  async headers() {
    return [
      {
        source: '/(.*)',
        headers: [
          { key: 'X-Content-Type-Options', value: 'nosniff' },
          { key: 'Referrer-Policy', value: 'strict-origin-when-cross-origin' },
          { key: 'Strict-Transport-Security',
            value: 'max-age=63072000; includeSubDomains; preload' },
          { key: 'Content-Security-Policy', value: "default-src 'self'" },
        ],
      },
    ]
  },

  // 3. Rewrites stay static — never built from headers/cookies/params
}

A few habits to layer on top:

  • Middleware is your authorization layer. Review middleware.ts against CVE-2026-64642's bypass triple — Turbopack + legacy middleware + single-locale i18n — and confirm none of them apply together in production.
  • Server Actions should validate payload size. CVE-2026-64646 is memory exhaustion in the Edge runtime; a hard cap on request body size is a cheap mitigation that survives the next regression.
  • Image Optimization should reject SVGs by default (see dangerouslyAllowSVG: false above). The framework already gives you the toggle — turn it on unless you have a deliberate, sanitized SVG pipeline.

What does this say about Next.js security going forward?

Vercel announced a monthly security release program alongside this batch. That changes your upgrade rhythm. "When the next CVE drops" stops being a question of if and becomes a calendar event. The pragmatic move is to wire a recurring dependency audit into CI:

# .github/workflows/security.yml (sketch)
- name: Audit dependencies
  run: |
    pnpm audit --prod
    pnpm outdated next

Treat an outdated next past the published security floor as a failing check. Monthly advisories land best when monthly upgrade work is already budgeted — not crammed into the sprint after the disclosure.

And what doesn't change when the framework does?

Every coordinated patch like this is a reminder that the framework layer underneath an app is the noisiest part — new versions, monthly advisories, deprecations, Turbopack switches. Worth its own audit ritual, yes. But the surface your users actually touch — the buttons, lists, forms, sheets — shouldn't churn with it. A <Button> that renders the same on iOS, Android, and the web, regardless of whether Next.js shipped an SSRF fix or a major version bump, is the durable layer. Ship the patches; keep the UI consistent.

If your contribution graph is a long queue of "bump Next.js, retest the navigation, retest the sheets, retest the forms" — that's the piece worth decoupling. The security work and the framework churn stay where they belong. The cross-platform UI doesn't have to follow.

backendannouncementvercel
OTF SaaS Dashboard Kit

Ship the product, not the setup.

  • 11 production screens — auth, billing, team, analytics, settings
  • Real database, payments, and login — all wired on day 1
  • AI configs pre-tuned so your agent extends instead of regenerates