DEV Community

jamilxt
jamilxt

Posted on

Two Critical Next.js RCE Fixes Ship With No CVE ID. npm audit May Never Tell You.

On October 14, Vercel did something it rarely does: it shipped a Next.js release outside the normal schedule, dropping everything to push out fixes for two critical vulnerabilities. Both allow unauthenticated remote code execution. Both score 9.5 on the CVSS v4 scale. A high-severity denial-of-service flaw rode along in the same release.

If you run a Next.js app and your only exposure signal is npm audit, here is the uncomfortable part. According to The Hacker News' coverage of the release, as of October 15 the use cache flaw and the Server Actions flaw had no CVE identifiers and no entries in the npm advisory feed that npm audit queries. Your dependency scanner can look straight at a vulnerable lockfile and report zero problems.

Full disclosure before the audit steps: I do not maintain a production Next.js application. Everything below comes from the official Next.js security advisory, the GitHub security advisories it links, and The Hacker News' detailed write-up, and I will flag which claims come from where. What I can add is the part the advisories skip: a concrete order of operations for finding out whether your app was actually exposed, not just whether it is theoretically vulnerable.

The three flaws, ranked by how much they should scare you

Flaw one: unauthenticated RCE through use cache (Critical, CVSS 9.5). Tracked as GHSA-673q-mjm6-r5xr on the Next.js side, with a related React advisory, GHSA-xqc2-xf4c-x3h3. The exposure window is narrow but real: App Router applications with Cache Components enabled, where a function marked use cache returns more than one typed array. Vercel lists no workaround and its advice is blunt: upgrade immediately even if your application does not have similar functions. Affected versions are 16.0.0 through 16.4.0, fixed in 16.4.1.

Flaw two: unauthenticated RCE through SVG image optimization (Critical, CVSS 9.5). This one is CVE-2026-96889 / GHSA-2464-fhr4-w9xw, a memory bug in librsvg, the library Next.js reaches through its bundled sharp image-processing package. If your Image Optimization API processes an attacker-supplied SVG while Next.js runs on glibc-based Linux, code execution is possible. The affected range is wide: 10.0.0 through 15.5.27, plus 16.0.0 through 16.4.0. There is a workaround this time: sharp 0.35.5 or later.

Flaw three: denial of service through Server Actions (High, CVSS 8.2). GHSA-p3m5-59mp-jv5r. Any App Router application with at least one Server Action can be pushed to full CPU utilization by crafted requests, which blocks every other request in that process. Versions 13.0.0 through 15.5.27 and 16.0.0 through 16.4.0 are affected. Pages Router applications and apps without Server Actions are not vulnerable.

One more detail worth knowing: per the official blog post, two of these fixes were postponed from the September security release because upstream dependencies were not ready. The bug in the React Server Components protocol itself was patched in the react-server-dom-webpack, react-server-dom-parcel, and react-server-dom-turbopack packages in versions 19.0.9, 19.1.10, 19.2.9, and 19.3.1.

The 15-minute audit, in order

Work through these five checks. The first two take minutes; the rest tell you whether you were exposed or just behind on patches.

Step one: find out what you are actually running. Not what package.json says, what the lockfile resolved:

npm ls next
npm ls sharp
Enter fullscreen mode Exit fullscreen mode

If next shows 16.4.1 or 15.5.28, the framework-level part is done and you can stop after step five. If it shows anything on the affected ranges above, keep going. Pay special attention to sharp here, because there is a trap: upgrading to 15.5.28 alone does not force a fixed sharp. A 15.x app can sit on the vulnerable 0.34.x line after the framework upgrade. Only 16.4.1 guarantees the patched sharp comes along.

Step two: patch, then rebuild and redeploy. Installing the package on your laptop changes nothing about what your users hit:

npm install next@16.4.1   # 16.x line
npm install next@15.5.28  # 15.x line, then verify sharp separately
npm ls sharp              # must show 0.35.5 or later on 15.x
Enter fullscreen mode Exit fullscreen mode

Then rebuild and redeploy. The advisories and every operator write-up stress this because the vulnerable code paths live in server bundles, and an unpinned deploy pipeline can happily keep shipping last month's build with this month's lockfile.

Step three: determine your glibc exposure. The librsvg flaw is scoped to glibc-based Linux, which covers most Docker images built on Debian or Ubuntu bases. Check what your production image uses:

ldd --version | head -1
Enter fullscreen mode Exit fullscreen mode

If that prints a musl reference, you are on an Alpine-style base and outside the stated scope. The advisory language matters here: it says the code execution path applies when Next.js runs on glibc-based Linux, so do not treat musl as a certified immunity, treat it as outside the documented blast radius. If your image is Debian or Ubuntu based, and your app renders user-uploaded SVGs through Image Optimization, assume the path was reachable.

Step four: grep for the triggering patterns. Two searches tell you whether flaws one and three applied to your code:

grep -rn "use cache" app/ src/
grep -rln "use server" app/ src/
Enter fullscreen mode Exit fullscreen mode

The first matters only if you are on Next.js 16 with Cache Components enabled, and only if a cached function returns more than one typed array. The second matters on any App Router version in the affected range, because a single Server Action anywhere in the codebase was enough to expose the DoS. And the honest answer to "does an App Router app have at least one Server Action" is almost always yes, which is exactly why the third flaw, the one rated lowest of the three, is the one most likely to have applied to your app.

Step five: check the logs for the worst case. If you were exposed before patching, the evidence lives in your access and application logs. For the SVG flaw, look for image optimization requests with .svg sources in the weeks since late September, when the underlying librsvg bug was published on September 23 and fixed in sharp on September 27. For the DoS, look for single processes pinning a core. To be clear about what is known: The Hacker News reported that as of October 15, there were no public reports of any of the three flaws being exploited in the wild. This is a patch-first story, not a breach story. The log check is about closing the loop on your own deployment, not panic.

Why your scanner stayed quiet

This is the part I would keep, even after you patch, because it generalizes.

CVE identifiers are the currency of the automated security world. Dependabot, npm audit, Snyk, and most CI gates key off advisory databases, and those databases key off CVEs. The use cache flaw had no CVE as of October 15. The Server Actions flaw had no CVE either. Two critical-severity RCEs in one of the most deployed web frameworks on the planet, and the automated pipeline that most teams trust had nothing to say about either.

The SVG flaw shows the other failure mode. The underlying librsvg bug was public on September 23 and Red Hat scored it 7.8 with a user-interaction requirement, which sounds manageable. Vercel scored the Next.js exposure 9.5 and network-reachable, because in a Next.js app the "user interaction" is an anonymous HTTP request to your image optimization endpoint. Same bug, two scores, and the context that made it critical only exists one layer up the dependency chain. No scanner resolves that for you, because context lives in your architecture, not in the package graph.

What I would take from this as a standing practice:

  • Advisory feeds are downstream of disclosure, and disclosure is slow. For the two or three frameworks your business actually runs on, subscribe to their release notes or security blog directly. The 30 seconds it takes beats waiting for a CVE to propagate.
  • Out-of-band releases are a signal, not noise. A maintainer breaking their release cadence is telling you the calculus changed. Treat same-day patching of out-of-band releases as the default.
  • Install is not deploy. Rebuild, redeploy, then verify the running version, because the lockfile you patched and the bundle your users execute are different artifacts until you prove otherwise.
  • Pin your awareness to transitive dependencies on runtime paths. sharp, image processors, PDF libraries, anything that parses attacker-controlled bytes. These are where a 7.8 library bug becomes a 9.5 application bug.

There is a reason this pattern keeps repeating. Every modern framework is a thin layer over a pile of C libraries and upstream runtimes, and the framework's security team can only move as fast as those upstreams. Vercel postponed two of these fixes from September for exactly that reason. The dependency chain is not an implementation detail anymore. It is your attack surface.

The checklist, compressed

If you only do five things after reading this:

  1. Run npm ls next. Anything below 16.4.1 or 15.5.28 needs patching today.
  2. On 15.x, run npm ls sharp and confirm 0.35.5 or later. The framework upgrade alone does not guarantee it.
  3. Rebuild and redeploy, then verify the deployed build picked up the change.
  4. Grep your codebase for use cache and use server to know which of the three flaws actually applied to you.
  5. Do not wait for npm audit to flag the two CVE-less flaws. It may never flag them.

I write about backend engineering, security, and AI infrastructure every week. Subscribe, it is free.

Did the October 14 update land on any of your apps, and how long did the patch-and-redeploy cycle take you? And honestly, did your dependency scanner catch this one, or did you hear about it the way most people did, from a headline?

Top comments (0)