Next.js emergency patch: two critical RCE flaws allow unauthenticated remote code execution

The CyberSec Guru

Next.js Critical RCE Vulnerabilities: CVE-2026-96889

If you like this post, then please share it:

Buy me A Coffee!

Support The CyberSec Guru’s Mission

🔐 Fuel the cybersecurity crusade by buying me a coffee! Why your support matters: Zero paywalls: Keep the main content 100% free for learners worldwide.

“Your coffee keeps the servers running and the knowledge flowing in our fight against cybercrime.”☕ Support My Work

Buy Me a Coffee Button

Vercel has shipped an out-of-band security update for Next.js that fixes two critical remote code execution vulnerabilities, both rated CVSS 9.5, and a high-severity denial-of-service flaw. Either RCE flaw lets an unauthenticated attacker run arbitrary code on the server. One sits in the caching layer of React Server Components. The other is a memory corruption bug in the SVG image processing pipeline. The fixes landed on October 14, 2026, in versions 16.4.1 (Active LTS) and 15.5.28 (Maintenance LTS).

Two things make this patch cycle unusual. The use cache flaw has no workaround, so only a full upgrade closes it. The SVG flaw has the widest version range of any Next.js vulnerability disclosed this year, 10.0.0 through 15.5.27 and 16.0.0 through 16.4.0. Next.js runs millions of production applications, from startups to Fortune 500 companies, so the exposure is large. Below I go through what happened, how the exploits work, who is at risk, and what to do now.

The three vulnerabilities at a glance

AdvisoryVulnerabilityCVSSAffected versionsFixed in
GHSA-673q-mjm6-r5xrRCE via use cache returning typed arrays9.5 Critical16.0.0 to 16.4.016.4.1
CVE-2026-96889 (GHSA-2464-fhr4-w9xw)RCE via SVG in Image Optimization API9.5 Critical10.0.0 to 15.5.27, 16.0.0 to 16.4.015.5.28 (with sharp 0.35.5 or later), 16.4.1
GHSA-p3m5-59mp-jv5rDoS via Server Actions CPU exhaustion8.2 High13.0.0 to 15.5.27, 16.0.0 to 16.4.015.5.28, 16.4.1

Vulnerability 1: RCE in use cache functions that return typed arrays (GHSA-673q-mjm6-r5xr)

What use cache is and why it matters

Next.js 16 introduced Cache Components, which bring granular caching to React Server Components. The use cache directive marks a function as cacheable, so its return value is stored and reused across requests. It belongs to the wider push toward Partial Prerendering (PPR), where static and dynamic content share a single route.

The cache serializes return values into a format that can travel from the server to the client and back. When a use cache function returns multiple typed arrays (Uint8Array, Float64Array, Int32Array and similar), the serializer has to handle those binary structures carefully. That is where the flaw sits.

Root cause: improper input validation in React Server Components

The bug originates in React Server Components, in the packages react-server-dom-webpack, react-server-dom-parcel and react-server-dom-turbopack, versions 19.0.0 through 19.3.0. React’s own advisory describes it as affecting “extremely rare cases where responses transport multiple typed arrays and an attacker-controlled value”.

In practice, the serialization layer fails to validate the structure and content of typed arrays sent as part of a cached function’s return value. An attacker who can craft a request that triggers deserialization of a cached response containing multiple typed arrays can inject data that is then interpreted as executable code. The flaw is classified as CWE-20, improper input validation: the framework trusts the serialized payload without adequate sanitization.

Exploitation scenario

Three conditions have to line up:

  1. The application uses the App Router (not the Pages Router).
  2. Cache Components are enabled (cacheComponents: true in next.config.js).
  3. At least one use cache function returns multiple typed arrays.

The third condition sounds restrictive, but typed arrays turn up all over modern web code: image processing pipelines, cryptographic operations, WebSocket binary frames, file upload handlers, ML inference results. A use cache function that caches a processed image buffer or a binary protocol response could meet it without anyone intending that.

The exploit needs no authentication and no user interaction. An attacker sends a crafted HTTP request to the Next.js server. If the server routes it through the vulnerable serialization path, arbitrary code runs in the Node.js runtime with the full privileges of the application process. There is no known workaround. Vercel’s advisory says developers must upgrade even if their application does not appear to use such functions.

Why scanners will miss it

As of October 15, the use cache advisory had no CVE and did not appear in the npm advisory feed that npm audit reads. Automated dependency scanners will not flag it, so teams that rely only on npm audit or Snyk have no signal for this one. Checking versions by hand is the only reliable detection method.

📬 Stay Ahead of Cyber Threats

Get the latest cybersecurity news, critical vulnerabilities, threat intelligence, tutorials, and exclusive giveaways delivered straight to your inbox. No spam. Unsubscribe anytime.

Subscribe to the Newsletter →

Vulnerability 2: RCE via SVG processing in Image Optimization (CVE-2026-96889)

Affected versions

The SVG flaw is broad where the use cache flaw is narrow. It affects Next.js 10.0.0 through 15.5.27 and 16.0.0 through 16.4.0, which covers essentially every version released in the past several years. It is tracked as CVE-2026-96889 (also GHSA-2464-fhr4-w9xw) and carries a CVSS score of 9.5 from Vercel’s assessment. Red Hat scored the underlying library bug at 7.8, assuming different exploitability.

The attack chain: from SVG to shell

The bug is not in Next.js code. It is in librsvg, the open-source library that renders SVG images, which Next.js reaches through sharp, the image processing library bundled for the Image Optimization API.

The flaw is a use-after-free (CWE-416). When librsvg parses an SVG containing nested XML inclusions (XIncludes) with duplicate entity declarations, it frees an XML entity that the parser is still using. librsvg’s Rust code calls into libxml2, a C library, and the boundary between Rust’s memory management and C’s manual allocation creates a lifecycle mismatch. librsvg frees an xmlEntity pointer that libxml2 still holds, which leaves a dangling pointer an attacker can exploit.

The fix was committed on September 22, 2026. librsvg no longer frees xmlEntity pointers that libxml2 is still using. It shipped in librsvg 2.63.2 and sharp 0.35.5 on September 27.

Security researcher Rafael B. Dias (@rafabd1) published a proof-of-concept exploit chain called VectorFreed, which shows the path from the librsvg use-after-free to command execution in Node.js. It runs in four stages:

  1. Trigger the use-after-free with a crafted SVG containing nested XIncludes and duplicate entity names. librsvg frees the entity early and leaves a dangling pointer.
  2. Groom the heap. By controlling later allocations, the attacker places controlled data at the address the dangling pointer references.
  3. Hijack control flow. When the parser dereferences the dangling pointer, it reads attacker-controlled data, which in a vulnerable build can redirect execution.
  4. Execute a shell. In Node.js environments built on glibc, the standard C library on most Linux distributions, the primitive is enough to spawn a shell or run commands with the privileges of the Node.js process.

The Node.js build matters a great deal here. As sharp’s maintainer noted, the official Node.js binaries are not compiled as Position Independent Executables (PIE), so the main binary lacks ASLR, and that makes exploitation considerably easier. Most distribution-packaged Node.js binaries are PIE-enabled, which gives some mitigation. Docker containers and cloud deployments often use the official binaries, so the risk is higher there.

Is your application exposed?

By default, Next.js does not optimize SVG files through the Image Optimization API. Developers have to set dangerouslyAllowSVG: true in next.config.js to turn it on. There is a second, less obvious path, though. next/og, which generates social preview images, uses sharp and librsvg to render SVG-based images when it runs on the Node.js runtime (not Edge). Any application using next/og on Node.js may be exposed even without dangerouslyAllowSVG.

Applications that accept user-supplied SVG files and pass them to sharp are directly vulnerable too. CMS platforms, avatar upload systems and design tools are the usual examples.

Platform-specific impact

Exposure varies by hosting platform. Netlify says it serves image optimization through Netlify Image CDN rather than the function runtime, so the next/image path is not exercised there. It still recommends upgrading, because the next/og path is reachable on its platform. Vercel’s platform uses Edge Functions for image optimization by default, but applications that explicitly configure the Node.js runtime for image handling remain at risk. Self-hosted deployments on glibc-based Linux (most Docker images, Ubuntu, Debian, RHEL) are fully exposed.

Vulnerability 3: denial of service via Server Actions (GHSA-p3m5-59mp-jv5r)

The third flaw is a denial of service rated CVSS 8.2. It affects Next.js 13.0.0 through 15.5.27 and 16.0.0 through 16.4.0, the whole App Router era. It does not give an attacker code execution, but it is still serious.

It targets Server Actions, the feature that lets client components call server-side functions directly. In App Router applications that define at least one Server Action, crafted requests can drive excessive CPU usage in the server process. Node.js runs on a single-threaded event loop, so one CPU-bound operation can stop the process from handling any other request. The result is a complete denial of service for that process.

Server Actions are invoked through POST requests. The server deserializes the payload and runs the target function. Treat the next sentence as inference: the flaw likely sits in the deserialization or execution path, and my guess is an algorithmic complexity issue where a small input causes quadratic or exponential processing time.

Platforms that bill by response time, such as Vercel’s function invocations, take a double hit, because the attack also raises hosting costs. Applications that use the Pages Router or define no Server Actions are not vulnerable.

Like the use cache flaw, this one has no workaround. The only mitigation is upgrading to 15.5.28 or 16.4.1. Disabling Server Actions would break application functionality, and no configuration flag patches the vulnerable code path selectively.

Why image processing keeps producing serious flaws

This is the third image-pipeline vulnerability in Next.js since August 2026. In August, a flaw in libheif (reached through sharp) allowed code execution when the optimizer processed a crafted AVIF image. In September, a vulnerability in next/og let attacker-controlled text manipulate the SVG it generated. Now librsvg has produced a use-after-free that chains to RCE.

The pattern follows from how the stack is built. Next.js bundles sharp, and sharp bundles native libraries written in C, C++ and Rust: libvips, librsvg, libheif, libxml2. Each one parses complex file formats (SVG, AVIF, XML) that attackers can control. A memory safety bug in any of them becomes an RCE in every Next.js application that processes user-supplied images. The stack runs from JavaScript through Node.js, sharp, libvips, librsvg and libxml2, so one memory management error at the bottom can end as full system compromise at the top.

Vercel did not change its own image code in 16.4.1. The patch raises the bundled sharp version to 0.35.5, which carries the patched librsvg 2.63.2. If your application uses a globally installed librsvg (common in some Docker configurations), upgrading Next.js alone may not be enough. Confirm that the system-level librsvg is 2.63.2 or later.

Remediation

upgrade Next.js

# For Next.js 16.x applications
npm install [email protected]
# For Next.js 15.x applications
npm install [email protected]

After upgrading, rebuild and redeploy. A plain npm install without a rebuild may not fully apply the fix, especially if your deployment uses a pre-built artifact.

verify the sharp version

Next.js 16.4.1 pulls in sharp 0.35.5 automatically, because its package manifest requires it. Next.js 15.5.28 still accepts the older, affected sharp 0.34.x, and if sharp is already installed at that version, npm may not upgrade it. Check and fix it manually:

# Check the installed sharp version
npm ls sharp
# If it is below 0.35.5, update it explicitly
npm install [email protected]

check system-level librsvg

If your deployment uses a globally installed librsvg (common in Docker images based on Debian, Ubuntu or Alpine with system packages), verify the version:

# Check librsvg version on Debian/Ubuntu
dpkg -l librsvg2-2
# On RHEL/CentOS/Fedora
rpm -q librsvg2

You need librsvg 2.63.2 or later. If your base image ships an older version, update it or move to a base image that includes the patched library.

interim mitigation for the SVG flaw

If you cannot upgrade Next.js right away, for example because of a complex deployment pipeline, the SVG flaw has a stopgap. You can block sharp from decoding SVG images entirely:

const sharp = require('sharp');
sharp.block({ operation: ["VipsForeignLoadSvg"] });

This closes the attack vector for the Image Optimization path, and it also breaks any legitimate SVG processing in your application. It does nothing for the use cache or Server Actions vulnerabilities, which have no workaround and require the upgrade.

know what your scanner cannot see

npm audit and most dependency scanners will not detect the use cache or Server Actions flaws, because those advisories have no CVE identifiers and are not in the npm advisory feed. The SVG flaw does appear in sharp’s own advisory, so npm audit may flag it indirectly. Check versions manually.

Technical deep dive: the librsvg use-after-free

For security engineers and researchers, here is the mechanism behind CVE-2026-96889 in more detail. The flaw sits in the interaction between librsvg’s Rust code and libxml2’s C API.

librsvg delegates XML parsing to libxml2, which keeps an internal table of XML entities, named references like &myEntity; that expand to predefined content. When librsvg meets an XInclude directive (a mechanism for including one XML document inside another), it may parse a nested document that declares entities with the same names as entities in the parent document.

The bug appears when librsvg’s cleanup code frees an xmlEntity structure after processing the nested document without checking whether libxml2’s parser still references it. In C terms this is a use-after-free, or a double free: librsvg calls free() on memory that libxml2 still treats as valid. When libxml2 later accesses the freed entity, it reads attacker-controlled data placed at that address.

The fixing commit (8a1b0cd319e9af2d1e9cf878081dd77f227a0504) makes librsvg track entity ownership, so that it frees only entities it explicitly allocated and leaves alone the ones libxml2 created and manages.

Turning a use-after-free into reliable code execution means getting past modern memory protections. VectorFreed shows how that works on non-PIE Node.js binaries, which include the official binaries from the Node.js project. The freed xmlEntity structure contains a function pointer, or a pointer to a structure of function pointers, that libxml2 calls during later parsing. By controlling the heap layout, the attacker places a fake structure at the freed address with the function pointer redirected to a stack pivot gadget or straight to system(). When libxml2 dereferences the pointer and makes the call, execution flows to attacker-controlled code.

On PIE-enabled binaries, the base address is randomized, so the attacker cannot easily know where gadgets live. Information leaks through the SVG parsing process or other application-level disclosures could still bypass ASLR in targeted attacks. Vercel’s 9.5 rating, above Red Hat’s 7.8, reflects the fact that in a network-reachable Next.js context the attacker can trigger the bug remotely without user interaction.

Who is most at risk

Exposure depends on configuration and deployment.

Highest risk:

  • Applications using the App Router with Server Actions and Cache Components enabled.
  • Applications that process user-supplied SVG files through sharp, or through next/image with dangerouslyAllowSVG: true.
  • Applications using next/og on the Node.js runtime.
  • Self-hosted deployments on glibc-based Linux with non-PIE Node.js binaries.

Moderate risk:

  • Applications on the App Router without Cache Components or Server Actions, which are exposed to the SVG flaw only.
  • Applications on managed platforms where the image optimizer runs at the CDN edge (Netlify, some Vercel configurations). SVG impact is reduced there, but next/og paths may still be vulnerable.

Lower risk:

  • Applications using only the Pages Router. They are not vulnerable to the use cache or Server Actions flaws, though the SVG flaw still applies if image optimization is in use.
  • Applications with images.unoptimized: true and no next/og usage.

Timeline of disclosure and response

DateEvent
September 22, 2026librsvg use-after-free fix committed
September 23, 2026CVE-2026-96889 made public
September 27, 2026sharp 0.35.5 released with librsvg 2.63.2
October 14, 2026Next.js 16.4.1 and 15.5.28 released; advisories published
October 15, 2026No public reports of active exploitation as of this writing

Going from CVE publication to a Next.js patch in 21 days is quick. It also means that for nearly three weeks, applications processing SVGs through sharp were exposed to a publicly known RCE. Organizations with slow patch cycles should treat this as an emergency update.

What this says about supply chain depth

Next.js does not contain the buggy code, and neither does sharp. The bug is in librsvg, a dependency of libvips, which sharp uses. It still shows up as a critical RCE in Next.js applications.

Vercel and the Next.js team responded rapidly and transparently, so I do not read this as a failing on their part. The issue is how deep npm supply chains run. They are now attack surfaces measured in gigabytes, and one memory safety bug in a Rust or C library can compromise millions of applications. The industry’s move toward Rust helps, since librsvg is written in Rust, but it still interfaces with C, and language boundaries remain dangerous. The xmlEntity pointer freed by Rust code was allocated by C code, a classic cross-language ownership bug.

A framework cannot carry your security for you. Monitor the native libraries your direct dependencies bundle, not only the dependencies themselves. npm audit is necessary and not sufficient. Container scanning, SBOM analysis and pinning of system-level library versions are now baseline practice for production Next.js deployments.

What to do now

I’d rank the October 2026 Next.js security release among the most significant patches in the framework’s history. It has two unauthenticated RCE flaws, one with no workaround and the other reaching back to version 10.0.0, and standard dependency scanners cannot detect the use cache flaw.

  1. Upgrade to Next.js 16.4.1 or 15.5.28.
  2. Verify that sharp is 0.35.5 or later.
  3. Check your system librsvg version.
  4. If you use next/og on Node.js, treat it as exposed.
  5. If you accept user-supplied SVGs, audit your processing pipeline.
  6. If you cannot upgrade yet, block SVG decoding in sharp as a stopgap. It covers the SVG path only.

There are no public reports of active exploitation, though a proof-of-concept chain for the SVG flaw is public. Patch before that changes.

Buy me A Coffee!

Support The CyberSec Guru’s Mission

🔐 Fuel the cybersecurity crusade by buying me a coffee! Your contribution powers free tutorials, hands-on labs, and security resources.

Why your support matters:
  • Writeup Access: Get complete writeup access within 12 hours
  • Zero paywalls: Keep the main content 100% free for learners worldwide

Perks for one-time supporters:
☕️ $5: Shoutout in Buy Me a Coffee
🛡️ $8: Fast-track Access to Live Webinars
💻 $10: Vote on future tutorial topics + exclusive AMA access

“Your coffee keeps the servers running and the knowledge flowing in our fight against cybercrime.”☕ Support My Work

Buy Me a Coffee Button

If you like this post, then please share it:

Exploits

Discover more from The CyberSec Guru

Subscribe to get the latest posts sent to your email!

Leave a Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Discover more from The CyberSec Guru

Subscribe now to keep reading and get access to the full archive.

Continue reading