PatchDay Alert
Analysis · 6 min read · 1,121 words By The Commentary Desk · Commentary

Vercel shipped the framework. You're shipping the patch

CVE-2026-44578 is a CVSS 8.6 SSRF in self-hosted Next.js. The fix for 13.x and 14.x users is a major-version migration, filed against your product team as a Dependabot chore.

Vercel shipped the framework. You're shipping the patch

If you’re on Next.js 13.x or 14.x and you self-host, the fix for CVE-2026-44578 is a major-version migration. There is no backport. Vercel’s changelog is explicit: patches are not planned for those lines, and the only supported path forward is upgrading to 15.x or 16.x.

That’s the whole post in two sentences, but it’s worth slowing down, because the org-chart consequences of those two sentences are where this gets uncomfortable.

The bug, briefly

The vulnerability is a server-side request forgery in the WebSocket upgrade path of Next.js’s built-in Node.js server. When a client sends an HTTP/1.1 request with Connection: Upgrade and Upgrade: websocket, Node fires a separate upgrade event, and Next.js routes that event through a handler that, until May 6, didn’t check whether the router actually marked the destination as a sanctioned external rewrite. The normal HTTP handler did. The upgrade handler didn’t. Hadrian’s writeup points at packages/next/src/server/lib/router-server.ts and the missing finished && parsedUrl.protocol && !statusCode gate; the fix applies the same triple check to the upgrade path.

The CVSS is 8.6, network, no auth, no user interaction, scope-changed, confidentiality-high. The primitive is read-only, which is the only reason it isn’t a 9.x. A public PoC shipped within days of the patch, runnable as TARGET=http://localhost:3000 ./exploit.sh, and Sploitus has it indexed. The canonical first request from any cloud SSRF is the IMDS endpoint at 169.254.169.254, and per Hadrian, the destination is pinned to port 80, which is exactly where every cloud’s metadata service listens.

Patches are 15.5.16 and 16.2.5, shipped May 6, 2026. The 14.x line, which is still in the affected range, is no longer receiving security patches at all.

Who pays for this

The structural cut is between Next.js apps that own their own http.Server and apps where someone else does. If you run next start on an EC2 box, ship the official output: 'standalone' Docker image, deploy to Render or Railway, or run on Kubernetes with a LoadBalancer and no L7 in front, you own the vulnerable code path. If you’re on Vercel, you don’t. Vercel’s platform doesn’t run the Next.js Node server in the first place; route handlers terminate per-invocation, and the underlying HTTP server isn’t reachable. Netlify says the same for Functions and Edge Functions, on the basis that they don’t support WebSocket upgrades at all.

So the vendor that built the framework is, structurally, not exposed to the bug it shipped. And the vendor that built the framework is the one telling 13.x and 14.x self-hosters to do a major-version migration to patch.

Hadrian’s exposure scan, which is a sampling extrapolation rather than a verified count, estimates ~740,000 Next.js servers on Shodan, ~118,700 on the default next start port 3000 with no reverse proxy, and ~79,000 instances vulnerable today. The methodology is worth treating with the appropriate skepticism, but even at a fraction of that number, the population is not small, and it skews toward the people who can’t just kick a deploy and walk away.

The Dependabot problem

Here is the part that makes this CVE different from a Microsoft Patch Tuesday item. Self-hosted Next.js is a product-engineering dependency. It lives in a package.json file inside a repo owned by the team that ships features. The CVE shows up as a Dependabot PR titled something like “bump next from 13.4.18 to 15.5.18,” which is structurally indistinguishable from any other breaking-change chore, and lands in the same queue as fifty other dependency bumps that nobody’s gotten to yet.

The security team can see the CVSS 8.6. They can file a ticket. They cannot merge the PR. The people who can merge the PR are looking at a two-major-version jump that crosses the App Router cutover, the caching-semantics changes, the Node version bumps, and whatever else Vercel decided to break between 13 and 15. That’s not a Monday-morning task, and it isn’t going to get prioritized against the roadmap unless somebody escalates it loudly.

Meanwhile the PoC is public, the exploit is a one-line shell invocation, and 169.254.169.254 is sitting there on every EC2 instance that hasn’t been migrated to IMDSv2.

What you can actually do this week

Find your version. If you’re on 15.x or 16.x self-hosted, the upgrade is a point release and you should just do it. If you’re on 13.x or 14.x self-hosted, the upgrade is a project, and in the meantime:

  • Strip the upgrade headers at the reverse proxy if the app doesn’t legitimately use WebSockets. Nginx takes proxy_set_header Upgrade "";. Anything fronted by Cloudflare’s CDN proxy or an ALB without WebSocket target-group config is already shielded; the malicious upgrade never reaches Node.
  • Enforce IMDSv2 on every instance running Next.js. AWS made IMDSv2 the default for new launches in mid-2024, but the change isn’t retroactive. AMIs baked before that flip, containers that don’t propagate the metadata-options block, Terraform modules pinning http_tokens = "optional" for backward compatibility — all of those still answer IMDSv1, and IMDSv1 is what a vanilla SSRF can talk to.
  • Block egress from the Next.js host to 169.254.169.254/32 and to RFC1918 ranges except known internal services. This is the belt against the IMDSv2 suspenders.

CVE-2026-44578 is not in CISA KEV as of 2026-05-14, which is the only piece of good news in this writeup, and it’s eight days old.

Why this keeps happening

The Vercel cutout is structural, not coincidental. A hosted platform that runs your framework in its own runtime owns the patching problem; a framework you self-host puts the patching problem inside your repo. Both arrangements are defensible. What isn’t defensible is shipping a security-only major-version migration as the supported remediation for two release lines that a large fraction of your users are still on, and treating the upgrade burden as somebody else’s operational problem.

The framework is free. The framework is also a security boundary. When the vendor decides that “upgrade across two majors” is the patch, the cost of that decision lands on the team that picked the framework, not the team that maintains it.

If you self-host Next.js, this CVE was filed against your dev team, not your security team. Get the ticket to the people who can merge the PR, give them a deadline, and harden the host in the meantime. PatchDay Alert will keep flagging these the morning the advisory drops; the merge is still yours.

Sources

Sources

Share

Related field notes

One email, every weekday morning.

You're in. Check your inbox.

Get the digest

Free. Weekday mornings. Plain English CVE triage.

Check your inbox to confirm.