JSX In, Shell Out — CVE-2026-94545 Turns Next.js ImageResponse Into a 9.5 RCE

On 22 September 2026, Vercel shipped Next.js 16.3.6 with a single security advisory that should make every team serving AI-generated sites sit up: CVE-2026-94545 (GHSA-vcvr-r3jv-pc5j), a CVSS 9.5 Critical remote code execution in the Node.js implementation of ImageResponse from next/og. Affected: Next.js 16.2.0 through 16.3.5. The trigger is almost embarrassingly ordinary — an app that puts attacker-controlled values, such as text read from the request URL, into a generated Open Graph image. That describes half the social-card endpoints on the modern web, and nearly all of them on vibe-coded ones.

The bug is in Satori; the blast radius is in Next.js

ImageResponse converts JSX and CSS into PNGs by way of Satori, Vercel's library for rendering layout to SVG first. Satori's same-day advisory says certain values reached its SVG output without being properly escaped — attacker-controlled strings in SVG elements, XML names, and internal style fields could be interpreted as SVG markup instead of plain text. The Satori fix (0.33.5) escapes text and attribute values before serializing, and Checkmarx's analysis of the fix commit confirms the prior version simply did not sanitize input before generating markup.

Why does an SVG-injection bug score 9.5 in Next.js but only 5.3 Moderate in Satori's own advisory? Because impact depends on what consumes the SVG. Vercel states that in Next.js, tainted values could reach vulnerabilities in other libraries Next.js depends on and lead to code execution — without naming those libraries. Satori used directly is an escaping bug; Satori embedded in next/og on a server is a shell. Two carve-outs limit the exposure: the Edge runtime build of ImageResponse is not affected, and neither is Next.js 15 (the companion 15.5.26 release adds extra hardening for next/og on that line).

What counts as attacker-controlled is broader than the advisory example

Vercel's advisory scopes affected apps as those that "pass attacker-controlled values into SVG content, attributes, or styles during image generation," with an example that takes a value from the request URL and places it inside an SVG title element. What the advisory does not say is whether ordinary element text — a heading inside a div, the common case for dynamic OG cards reading ?title= off the query string — also counts. Until that is clarified, treat any request-derived string flowing into ImageResponse as in scope. To find exposure, search for ImageResponse imported from next/og in route handlers (rendered per request) and opengraph-image files (rendered at build time or per request).

This is the second time this year the Next.js rendering pipeline has bitten AI-generated front ends — in May we covered CVE-2026-44578, a WebSocket SSRF in the same generator-adjacent surface. OG-image endpoints are exactly the kind of code coding agents emit without a second thought: public, parameter-driven, and boring enough that nobody reviews them.

The detection gap is the real story

As of 23 September, The Hacker News found that npm audit did not flag the affected 16.3.5, the advisory was not yet in the GitHub Advisory Database, and no CVE record had been published — and Satori is bundled inside the Next.js package, so it never appears as a dependency in your lockfile for scanners to key on. Affected releases have been installable since the 16.2 line shipped in March, giving the exposure window roughly six months. Vercel's advisory and announcement also do not say whether apps hosted on Vercel are protected (for two critical August flaws the company explicitly said hosted apps needed no upgrade) and offer no way to check whether an affected route was abused before patching. No public exploit code or in-the-wild reports had surfaced as of 23 September — but with no detection telemetry either, absence of reports is thin comfort.

What to do today

  • Upgrade to next@16.3.6 — it is the only patched version. As of the advisory date there was no fixed 16.2-line release on npm, so 16.2 deployments must move to 16.3.6. Check next --version directly; do not trust a clean npm audit.
  • Inventory every next/og ImageResponse call site in route handlers and opengraph-image files, and map which ones accept request-derived input. Assume query strings, path params, headers, and CMS content are all attacker-controlled.
  • If patching must wait, strip attacker-controlled values from SVG content, attributes, and styles rendered by the Node.js ImageResponse — the vendor's interim workaround. Do not rely on switching runtimes: the Edge runtime is marked deprecated in the Next.js docs and the advisory does not recommend the move.
  • Direct Satori users: upgrade to 0.33.5 and audit how your SVG output is consumed downstream — the 5.3 rating assumes a benign sink, which a server-side image pipeline is not.
  • Treat generated marketing surfaces as attack surface. OG cards, sitemaps, RSS feeds, and preview endpoints are unauthenticated by design and increasingly agent-authored. Put them in the same review bucket as any other request-handling code your agents emit.

Sources: