CVE
CVE-2026-96889, CVE-2026-94482, CVE-2026-114139
CWE
CWE-502, CWE-416, CWE-1395, CWE-693, CWE-770
Affected Surface
- npm package `next` versions `>= 16.0.0, <= 16.4.0` for `GHSA-673q-mjm6-r5xr` (`use cache` typed-array RCE, fixed in `16.4.1`)
- npm package `next` versions `>= 10.0.0, <= 15.5.27` and `>= 16.0.0, <= 16.4.0` on glibc-based Linux when processing SVGs via `sharp < 0.35.5` (`GHSA-2464-fhr4-w9xw` / `CVE-2026-96889`, fixed in `15.5.28` and `16.4.1`, with an existing-lockfile caveat on `15.5.28`)
- npm package `next` versions `>= 13.0.0, <= 15.5.27` and `>= 16.0.0, <= 16.4.0` using App Router with Server Actions (`GHSA-p3m5-59mp-jv5r` / `CVE-2026-94482`)
- npm package `@sentry/nextjs` versions `>= 9.36.0, < 9.47.2`, `>= 10.0.0-alpha.0, < 10.75.2`, and `>= 11.0.0-alpha.0, < 11.0.0-rc.1` when `tunnelRoute` is configured on a Webpack build (`GHSA-mchm-gjx6-7h55` / `CVE-2026-114139`)
TL;DR
On 22 October 2026, the GitHub Advisory Database published four reviewed high and critical advisories affecting Next.js applications (next and @sentry/nextjs), alongside the upstream librsvg advisory (GHSA-cpvr-w4j5-2mpg / CVE-2026-96889) that underlies the Next.js image-optimization flaw:
GHSA-673q-mjm6-r5xr(CVSS v4 9.5 Critical): Unauthenticated remote code execution in Next.js16.0.0through16.4.0applications using the App Router with Cache Components (use cache) when a cached function returns multiple typed arrays. There is no configuration workaround; upgrade tonext@16.4.1.GHSA-2464-fhr4-w9xw/CVE-2026-96889(CVSS v4 9.5 Critical): Unauthenticated remote code execution in Next.js10.0.0through15.5.27and16.0.0through16.4.0on glibc-based Linux when the Image Optimization API (ornext/ogImageResponse) processes SVG files throughsharp < 0.35.5. Watch out for a lockfile trap on the15.5line:next@15.5.28declares"sharp": "^0.34.3 || ^0.35.5"inoptionalDependencies, so runningnpm install next@15.5.28on an existing project whose lockfile already resolvessharp@0.34.xleaves the vulnerablesharpbinary in place unless you explicitly upgrade or overridesharpto>= 0.35.5.GHSA-p3m5-59mp-jv5r/CVE-2026-94482(CVSS v4 8.2 High): Denial of service in Next.js13.0.0through15.5.27and16.0.0through16.4.0App Router applications that define at least one Server Action, allowing crafted requests to stall the Node.js event loop.GHSA-mchm-gjx6-7h55/CVE-2026-114139(CVSS v4 9.1 Critical): In@sentry/nextjs(>= 9.36.0, < 9.47.2,>= 10.0.0-alpha.0, < 10.75.2, and>= 11.0.0-alpha.0, < 11.0.0-rc.1),wrapMiddlewareWithSentry()skipped the application’s Next.js middleware for any request whose pathname started withtunnelRoute(or matchedtunnelRoutewithout the requiredPOSTmethod and numericoandpquery parameters). When a page or API route resolves under that path (including root dynamic segments likeapp/[locale]/...), attackers can reach the route while completely bypassing middleware-enforced authentication.
Upgrade next to 16.4.1 or 15.5.28, verify npm ls sharp resolves to 0.35.5 or newer, and upgrade @sentry/nextjs to 10.75.2, 9.47.2, or 11.0.0-rc.1.
Affected packages and projects
| Ecosystem | Package | Advisory / CVE | Severity | Affected versions | Fixed versions |
|---|---|---|---|---|---|
| npm | next | GHSA-673q-mjm6-r5xr | Critical (CVSS 9.5) | >= 16.0.0, <= 16.4.0 | 16.4.1 |
| npm | next | GHSA-2464-fhr4-w9xw (CVE-2026-96889) | Critical (CVSS 9.5) | >= 10.0.0, <= 15.5.27 and >= 16.0.0, <= 16.4.0 | 15.5.28, 16.4.1 (with sharp >= 0.35.5) |
| npm | next | GHSA-p3m5-59mp-jv5r (CVE-2026-94482) | High (CVSS 8.2) | >= 13.0.0, <= 15.5.27 and >= 16.0.0, <= 16.4.0 | 15.5.28, 16.4.1 |
| npm | @sentry/nextjs | GHSA-mchm-gjx6-7h55 (CVE-2026-114139) | Critical (CVSS 9.1) | >= 9.36.0, < 9.47.2, >= 10.0.0-alpha.0, < 10.75.2, >= 11.0.0-alpha.0, < 11.0.0-rc.1 | 9.47.2, 10.75.2, 11.0.0-rc.1 |
Rust / C (via sharp / libvips) | librsvg | GHSA-cpvr-w4j5-2mpg (CVE-2026-96889, RUSTSEC-2026-0305) | High (CVSS 7.8) | < 2.57.5, 2.60.0-beta.0 to < 2.60.3, 2.61.0 to < 2.61.5, 2.62.0-beta.0 to < 2.62.4, 2.63.0-beta.0 to < 2.63.2 | 2.57.5, 2.60.3, 2.61.5, 2.62.4, 2.63.2 |
Technical analysis
1. GHSA-673q-mjm6-r5xr: React Flight stream prefix collision and detached ArrayBuffer transport in use cache
Next.js 16’s Cache Components (use cache) serialize and deserialize return values through the React Server Components (Flight) wire protocol (react-server-dom-webpack and react-server-dom-turbopack compiled inside packages/next/src/compiled/).
Next.js fix commit a4cea6aec5da ([lts-active][react] Improve Server Component transport protocol (#193)) makes two changes across the bundled Flight client and server runtimes:
- Separating stream form-field prefixes from part IDs: In
processReply()on the Flight client (react-server-dom-*-client.*.js),serializeReadableStream()andserializeReader()previously wrote stream control chunks ("$o" + entry.toString(16)and"C") directly underformFieldPrefix + streamId, sharing the same key namespace as regular part IDs (formFieldPrefix + nextPartId++). The patch namespaces stream fields understreamPrefix = formFieldPrefix + "S" + streamId:function serializeReader(reader) { function progress(entry) { if (entry.done) - data.append(formFieldPrefix + streamId, "C"), + data.append(streamPrefix, "C"), pendingParts--, 0 === pendingParts && resolve(data); else try { var partJSON = JSON.stringify(entry.value, resolveToJSON); - data.append(formFieldPrefix + streamId, partJSON); + data.append(streamPrefix, partJSON); reader.read().then(progress, reject); } catch (x) { reject(x); } } null === formData && (formData = new FormData()); var data = formData; pendingParts++; - var streamId = nextPartId++; + var streamId = nextPartId++, + streamPrefix = formFieldPrefix + "S" + streamId; - Rejecting detached
ArrayBufferviews inwriteChunk(): On the server side (react-server-dom-*-server.*.js), when a function returns multiple typed-array views backed by the same underlyingArrayBufferand one operation detaches the buffer,chunk.byteLengthbecomes0. Previously,writeChunk()silently skipped any chunk with0 === chunk.byteLength, leaving the Flight binary framing out of sync with the length headers emitted for the typed-array rows. The patchedwriteChunk()checksArrayBuffer.prototype.detachedwhenever0 === chunk.byteLengthand aborts serialization:if (0 === chunk.byteLength) { if (supportsArrayBufferDetached && chunk.buffer.detached) throw Error( "Cannot transport a detached buffer. This usually happens when trying to transport multiple buffer-spanning views on the same underyling buffer. Either reuse the exact same view by identity or copy the underlying buffer manually via `view.slice()`." ); }
Notice that Vercel’s advisory states: “You should upgrade immediately even if your application does not have similar functions.” Treat any Next.js 16.0.0 to 16.4.0 deployment using App Router as requiring an immediate upgrade to 16.4.1.
2. GHSA-2464-fhr4-w9xw (CVE-2026-96889): librsvg XInclude entity use-after-free in sharp and the 15.5.28 lockfile trap
When Next.js optimizes SVG images (for example when dangerouslyAllowSVG: true is configured on /_next/image, or when an application renders untrusted SVGs through next/og ImageResponse on Node.js), Next.js delegates rasterization to sharp, whose prebuilt @img/sharp-libvips-* binaries embed librsvg.
As detailed in GHSA-cpvr-w4j5-2mpg (CVE-2026-96889), librsvg uses libxml2 to parse XML. When an SVG document contains a nested <xi:include> (XInclude) while libxml2 is in the middle of expanding an internal XML entity, and the included document declares a new <!ENTITY ...> with the same name, both parses share librsvg’s XmlState entity map. Calling entity_insert() replaces the existing map entry, and its Rust Drop implementation calls xmlFreeNode() on the 144-byte xmlEntity struct while the outer xmlCtxtParseEntity() frame in libxml2 is still dereferencing it (GNOME/librsvg commit 8a1b0cd319e9). On glibc-based Linux, that use-after-free in the native image pipeline can be turned into remote code execution.
Next.js fixed this in 16.4.1 (commit 9571ec899f06) and 15.5.28 (commit 5e3b687b5edb) by bumping sharp to 0.35.5. However, compare the two commits in packages/next/package.json:
// Next.js 16.4.1 (commit 9571ec899f06)
"optionalDependencies": {
- "sharp": "^0.35.4"
+ "sharp": "^0.35.5"
}
// Next.js 15.5.28 (commit 5e3b687b5edb)
"optionalDependencies": {
- "sharp": "^0.34.3 || ^0.35.4"
+ "sharp": "^0.34.3 || ^0.35.5"
}
Because next@15.5.28 keeps ^0.34.3 in the union range, any project on the 15.5 line whose package-lock.json, pnpm-lock.yaml, or yarn.lock already pinned sharp 0.34.x (such as 0.34.5) already satisfies "^0.34.3 || ^0.35.5". Running npm install next@15.5.28 updates next while leaving the vulnerable sharp@0.34.x package untouched in node_modules/. Teams on Next.js 15 must explicitly upgrade or override sharp to ^0.35.5.
3. CVE-2026-114139 (GHSA-mchm-gjx6-7h55): @sentry/nextjs tunnelRoute middleware bypass
In @sentry/nextjs, setting tunnelRoute (for example tunnelRoute: '/monitoring') in next.config.js configures a Next.js rewrite rule that forwards browser Sentry envelope POST requests to Sentry’s ingest API. That rewrite rule only matches when both query parameters o (organization ID) and p (project ID) are present.
To keep the application’s own Next.js middleware (middleware.ts) from blocking those telemetry requests on Webpack builds, wrapMiddlewareWithSentry() in packages/nextjs/src/common/wrapMiddlewareWithSentry.ts returned an early x-middleware-next: 1 response whenever isPathnameUnderSentryTunnelRoute(url.pathname, tunnelRoute) returned true:
// Vulnerable check in @sentry/nextjs < 10.75.2 / < 9.47.2
export function isPathnameUnderSentryTunnelRoute(pathname: string, tunnelPath: string): boolean {
return pathname === tunnelPath || pathname.startsWith(`${tunnelPath}/`);
}
Because the middleware skip matched any HTTP method, required no query parameters, and matched every sub-path under ${tunnelPath}/, while the Next.js rewrite only intercepted requests to the exact tunnelPath with ?o=...&p=..., any request in the gap bypassed middleware.ts and went straight to the Next.js router:
- If
tunnelRouteis'/monitoring'(or'/api/tunnel') and your application has routes under/monitoring/adminor/api/tunnel/..., or - If your application uses a root dynamic route segment such as
app/[locale]/dashboard/page.tsx(which matches/monitoring/dashboardwithlocale = "monitoring"),
an unauthenticated GET or POST request to that path skips middleware.ts completely. If middleware is the only place enforcing authentication or authorization for that route, the attacker reaches the route unauthenticated.
Commit 878b685c85dc (PR #24499, released in 9.47.2, 10.75.2, and 11.0.0-rc.1) replaces the prefix check with isSentryTunnelRequest(), requiring request.method === 'POST', an exact pathname match (tunnelPath or ${tunnelPath}/), and numeric values for every o and p query parameter:
export function isSentryTunnelRequest(request: Request, tunnelPath: string): boolean {
if (request.method !== 'POST') {
return false;
}
const url = new URL(request.url);
if (url.pathname !== tunnelPath && url.pathname !== `${tunnelPath}/`) {
return false;
}
return ['o', 'p'].every(key => {
const values = url.searchParams.getAll(key);
return values.length > 0 && values.every(value => /^\d+$/.test(value));
});
}
Detection and remediation
1. Check next, sharp, and @sentry/nextjs versions in lockfiles and node_modules
Run the following checks across every Next.js repository:
# Check resolved versions of next, sharp, and @sentry/nextjs
npm ls next sharp @sentry/nextjs 2>/dev/null || pnpm list next sharp @sentry/nextjs 2>/dev/null || true
# Search lockfiles for vulnerable next, sharp (< 0.35.5), and @sentry/nextjs versions
rg -n '"(next|sharp|@img/sharp-libvips-[^"]+|@sentry/nextjs)"\s*:\s*"[^"]*"' \
package.json package-lock.json pnpm-lock.yaml yarn.lock 2>/dev/null
# Check whether dangerouslyAllowSVG or tunnelRoute is enabled in Next.js configs
rg -n 'dangerouslyAllowSVG|tunnelRoute|use cache|ImageResponse' \
next.config.* src app pages middleware.* 2>/dev/null
2. Upgrade and pin sharp >= 0.35.5
- Upgrade Next.js and
sharptogether:
After upgrading, run# On Next.js 16.x (also upgrade if on 16.0 - 16.3, as 16.3 has no separate patch) npm install next@16.4.1 sharp@^0.35.5 # On Next.js 15.5.x (explicitly install sharp@^0.35.5 so the lockfile does not keep 0.34.x) npm install next@15.5.28 sharp@^0.35.5npm ls sharp(orpnpm why sharp) and verify that no0.34.xor< 0.35.5copy remains in the lockfile. - Redeploy active preview and branch deployments: Serverless preview URLs built before the upgrade continue running the vulnerable
nextandsharpbundles until they are redeployed or deleted. - Upgrade
@sentry/nextjs: Move to10.75.2(for v10),9.47.2(for v9), or11.0.0-rc.1(for v11). As defense in depth, do not rely solely onmiddleware.tsfor access control when using root dynamic segments such asapp/[locale]/...; verify the session inside the server component, route handler, or data-access layer as well.
Timeline
- 2026-10-14: Vercel releases Next.js
16.4.1and15.5.28out of band for two issues postponed from the September security release plus a Server Actions DoS fix. - 2026-10-15: Independent analyses flag that
next@15.5.28retains"sharp": "^0.34.3 || ^0.35.5"inoptionalDependencies, leaving existingsharp@0.34.xlockfile pins unpatched after a standardnextbump. - 2026-10-21 (21:17 UTC): NVD publishes
CVE-2026-114139for the@sentry/nextjstunnelRoutemiddleware bypass. - 2026-10-22 (15:50 to 16:42 UTC): The GitHub Advisory Database publishes reviewed advisories
GHSA-p3m5-59mp-jv5r(CVE-2026-94482),GHSA-cpvr-w4j5-2mpg(CVE-2026-96889inlibrsvg),GHSA-2464-fhr4-w9xw(Next.js SVG RCE),GHSA-mchm-gjx6-7h55(CVE-2026-114139in@sentry/nextjs), andGHSA-673q-mjm6-r5xr(Next.jsuse cachetyped-array RCE).
From research to remediation
Check whether this pattern exists in your codebase
Turn this research into a remediation workflow. Scan dependencies and package manifests for similar supply-chain risk, then prioritize fixes with reachability context.
References
- Next.js advisory GHSA-673q-mjm6-r5xr (use cache typed-array RCE)
- Next.js advisory GHSA-2464-fhr4-w9xw (Image Optimization SVG RCE via CVE-2026-96889)
- Next.js advisory GHSA-p3m5-59mp-jv5r (CVE-2026-94482 Server Actions DoS)
- Sentry-JavaScript advisory GHSA-mchm-gjx6-7h55 (CVE-2026-114139 tunnelRoute middleware bypass)
- Librsvg advisory GHSA-cpvr-w4j5-2mpg (CVE-2026-96889 XInclude entity use-after-free)
- Next.js security update blog post (v16.4.1 and v15.5.28)
- Netlify security changelog: Next.js and React security vulnerabilities
- Cafiyn analysis: Next.js 16.4.1 and 15.5.28 security update and sharp lockfile retention