Your social-preview image generator is a trojanized photocopier — it faithfully reproduces whatever the attacker slips into the feed tray, including their malware
CVE-2026-94545 is an unauthenticated remote code execution vulnerability in the Node.js ImageResponse implementation within next/og, the Next.js module responsible for generating Open Graph social-preview images. The root cause lives upstream in Satori (versions ≥0.0.27 <0.33.5), Vercel's JSX-to-SVG rendering library, which fails to properly escape certain values before embedding them in generated SVG output. When a Next.js 16.2.0–16.3.5 application passes attacker-controlled data — such as URL search parameters — into SVG content, attributes, or styles rendered by ImageResponse, the unescaped values are interpreted as live SVG markup. This injected markup then triggers code execution through *other upstream dependencies* in the Node.js SVG processing pipeline. The Edge runtime variant of ImageResponse is not affected, and Next.js 15.x is not vulnerable to the RCE (though 15.5.26 adds related hardening). Fixed in Next.js 16.3.6 and Satori 0.33.5.
Vercel's own advisory (GHSA-vcvr-r3jv-pc5j) rates this CRITICAL at CVSS 4.0 9.5, while the underlying Satori advisory (GHSA-wx4j-mvgx-mqwp) is rated only Moderate at 5.3. The gap reveals the real story: Satori's SVG injection alone is a moderate output-escaping flaw, but *in the specific context of Next.js Node.js ImageResponse and its dependency chain*, the injection escalates to full RCE. The 9.5 score is defensible for the subset of apps that wire untrusted input into ImageResponse, but it overstates the risk for the broader Next.js installed base. Many deployments never use ImageResponse; many that do use static content or the Edge runtime. The affected version window is narrow — only Next.js 16.2.0 through 16.3.5, released over roughly four months in mid-2026. Enterprise teams still on 14.x or 15.x are entirely unaffected. The CRITICAL label will cause unnecessary panic for the majority of Next.js operators while being absolutely appropriate for the minority running vulnerable OG-image endpoints with dynamic user input.
4 steps from start to impact.
Identify a Next.js 16.2.x–16.3.5 endpoint using ImageResponse
x-powered-by: Next.js header (if not suppressed), characteristic /_next/ asset paths, and the presence of dynamic OG image endpoints (e.g., /api/og, /opengraph-image). The attacker confirms the endpoint accepts user-controlled parameters that influence the rendered image.- Target runs Next.js 16.2.0–16.3.5
- Target uses Node.js runtime (not Edge)
- Target exposes an ImageResponse endpoint that accepts user input
- Next.js 16.x adoption is still growing; many enterprises remain on 14.x/15.x
- Many Next.js deployments on Vercel or Cloudflare use Edge runtime by default, which is not affected
- Not all Next.js apps use ImageResponse at all
http.component:next.js, or HTTP header fingerprinting can identify Next.js version ranges. No specific scanner plugin for this CVE yet (1 day old).Craft malicious SVG injection payload
?title=<PAYLOAD> will be rendered as live SVG elements rather than escaped text content. The payload must be structured to exploit the downstream SVG processing dependencies in the Node.js pipeline.- Understanding of Satori's SVG generation internals
- Knowledge of which upstream dependency in the Node.js pipeline converts SVG injection to code execution
- No public PoC exploit code exists as of 2026-09-23
- The exact payload structure and upstream dependency exploitation path have not been disclosed
- Satori's escaping failure pattern is known, but weaponizing it to RCE requires chaining through undisclosed upstream deps
<svg, <foreignObject>, javascript:, <script>) in query parameters could catch naive payloads.Deliver payload via HTTP request to OG image endpoint
- Network access to the target endpoint (typically internet-facing)
- The application code passes the attacker-controlled value into SVG content/attributes/styles
- The application must actually interpolate user input into ImageResponse — static OG images are not vulnerable
- Some applications may validate or sanitize input before passing to ImageResponse
Achieve remote code execution on the server
- Steps 1-3 succeeded
- Vulnerable upstream dependencies are present (bundled with affected Next.js versions)
- Container-based deployments may limit post-exploitation blast radius
- Serverless/function-based architectures (Netlify, Vercel) isolate per-request, limiting persistence
- Network segmentation may constrain lateral movement
The supporting signals.
| In-the-Wild Exploitation | No known exploitation in the wild as of 2026-09-23. Security teams have confirmed no active campaigns. Disclosed only 1 day ago (2026-09-22). |
|---|---|
| Proof-of-Concept | No public PoC exploit code. The HORKimhab/CVE-2026-94545 GitHub repo is an empty template placeholder. Sploitus lists a reserved candidate entry with no functional exploit. The specific upstream dependency exploitation path remains undisclosed. |
| EPSS Score | Not yet scored — CVE is <24 hours old. Expect EPSS to populate within 1-2 weeks. Given no PoC and no ITW exploitation, initial EPSS will likely be low-moderate. |
| KEV Status | Not listed in CISA Known Exploited Vulnerabilities catalog. |
| CVSS Vector | Vercel GHSA: CVSS 4.0 9.5 Critical — CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:H/VI:H/VA:H/SC:H/SI:H/SA:H. Satori GHSA: CVSS 4.0 5.3 Moderate — CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:P/VC:N/VI:N/VA:N/SC:H/SI:H/SA:N. The delta shows RCE impact comes from the Next.js dependency chain, not Satori alone. |
| Affected Versions | Next.js ≥16.2.0 <16.3.6. Satori ≥0.0.27 <0.33.5. Next.js 15.x and earlier are not affected by the RCE. Edge ImageResponse runtime is not affected. |
| Fixed Versions | Next.js 16.3.6 (Active LTS), Next.js 15.5.26 (hardening only, not vulnerable to RCE). Satori 0.33.5. Nuxt OG Image module also affected via Satori — see nuxt-modules/og-image#692. |
| Scanning / Exposure | Per W3Techs (Sep 2026), Next.js powers 3.4% of all websites (~444K servers per Shodan). However, the vulnerable subset is narrow: only 16.2.x–16.3.5, only Node.js runtime, only those passing user input to ImageResponse. Realistic vulnerable population is a small fraction of the total Next.js install base. |
| Disclosure Date | 2026-09-22 — coordinated disclosure by Vercel with same-day patch release (Next.js 16.3.6). |
| Reporters | RaghavMaheshwari124 and rafabd1 via Vercel's Open Source Bug Bounty on HackerOne. |
Why this verdict
- Unauthenticated RCE is real but conditional: When the chain succeeds — Next.js 16.2.x–16.3.5, Node.js runtime, user input wired to ImageResponse — it is full unauthenticated RCE from the internet with no user interaction. This baseline impact is severe and anchors the assessment at HIGH minimum.
- Narrow version window compresses exposure: Only Next.js 16.2.0–16.3.5 is affected (~4 months of releases in mid-2026). Enterprise Next.js deployments skew toward stable LTS tracks; many remain on 14.x or 15.x. This significantly reduces the reachable population compared to a vuln affecting all Next.js versions.
- Feature-gated attack surface: The vulnerability requires the application to (a) use
ImageResponseat all and (b) pass attacker-controlled input into SVG rendering. While this is the documented/standard pattern for dynamic OG images, it is still an opt-in feature. Apps with static OG images, no OG images, or Edge-runtime ImageResponse are unaffected. - Edge runtime exclusion removes major deployment class: Vercel's own platform and Cloudflare Workers use the Edge
ImageResponseimplementation, which is not vulnerable. This excludes a large share of production Next.js deployments from the vulnerable population. - No PoC, no ITW, 1-day-old disclosure: As of 2026-09-23, no public exploit code exists and no active exploitation has been observed. The specific upstream dependency exploitation path remains undisclosed. This buys defenders time but should not be relied upon — the escaping flaw in Satori is well-characterized and weaponization is a matter of when, not if.
- Role multiplier: Next.js is an application-tier web framework. (a) *Low-value role*: dev/staging instances — RCE yields dev credentials, limited blast radius. (b) *Typical role*: production web application server — RCE yields application secrets (env vars, DB creds), customer data access, host-level compromise. Blast radius is host-to-tenant. (c) *High-value role*: Next.js could serve admin dashboards or internal tools, but it is not canonically a domain controller, identity provider, hypervisor, CI/CD engine, or backup system. The component itself does not occupy the high-value-role catalog at ≥10% of its install base. Blast radius caps at tenant/application level, not fleet or domain. No floor override applies.
Why not higher?
This does not reach CRITICAL because the vulnerable population is a narrow subset of the already-subset of Next.js 16.x deployments: only those on 16.2.0–16.3.5, only using Node.js runtime (not Edge), only passing user-controlled input to ImageResponse. Next.js is an application-tier component, not a canonical high-value infrastructure role (not a DC, hypervisor, IdP, or network edge appliance). The blast radius of successful exploitation is host-to-tenant, not fleet or domain scale. Additionally, no public PoC or ITW exploitation exists 1 day after disclosure.
Why not lower?
This cannot be MEDIUM because when the prerequisites are met, the result is unauthenticated, zero-interaction RCE from the internet — the most severe impact class. The vulnerable code pattern (interpolating searchParams into ImageResponse) is the documented standard usage shown in Next.js's own examples, so the friction of 'specific code pattern required' is lower than it appears. Next.js powers 3.4% of all websites with major enterprise adopters (GitHub, Netflix, OpenAI), so even the narrow vulnerable subset represents a meaningful number of production endpoints. A weaponized exploit is likely to emerge within weeks given the Satori escaping flaw is well-characterized.
What to do — in priority order.
- Upgrade to Next.js 16.3.6 immediately — This is the definitive fix. The upgrade patches both the Satori SVG escaping flaw and the vulnerable upstream dependencies. Deploy within 30 days per the noisgate remediation SLA for HIGH severity. Given the RCE impact and likelihood of PoC emergence, prioritize this over the 30-day window if possible.
- Audit all ImageResponse handlers for user-controlled input — Search your codebase for
ImageResponseusage and trace whether anysearchParams,params, headers, cookies, or other request-derived values flow into SVG content, attributes, or styles. If they do and you cannot immediately upgrade, remove the user-controlled interpolation or replace it with a static/allow-listed value. This is Vercel's official workaround. - Switch affected ImageResponse endpoints to Edge runtime — Add
export const runtime = 'edge'to route files containing ImageResponse handlers. The EdgeImageResponseimplementation is not vulnerable to this RCE. This provides immediate risk elimination while you plan the version upgrade. Deploy within 30 days per noisgate mitigation SLA. - Deploy WAF rules to block SVG injection in OG image endpoint parameters — Add WAF rules on your edge/CDN layer (Cloudflare, AWS WAF, Akamai) to detect and block SVG-like markup (
<svg,<foreignObject>,<script>,javascript:,xmlns) in query parameters targeting your OG image endpoints (e.g.,/api/og,/opengraph-image). This is defense-in-depth — it may not catch all payloads but raises the bar. Deploy within 30 days. - Enforce least-privilege for Node.js application processes — Ensure Next.js processes run as non-root, with minimal filesystem permissions and no access to host-level secrets beyond what the application requires. Use container isolation (read-only root filesystem, no-new-privileges, dropped capabilities) to limit post-exploitation impact.
- Network-level IP blocking — OG image endpoints must be accessible to social media crawlers (Facebook, Twitter, LinkedIn, Slack) from diverse IP ranges, so IP allow-listing is impractical without breaking social preview functionality.
- CSP headers — Content Security Policy is a browser-side control that has no effect on server-side SVG processing and RCE. The vulnerability executes in the Node.js process, not in a browser.
- Upgrading Satori alone without upgrading Next.js — Next.js bundles a compiled copy of
@vercel/ogincluding Satori. Simply updating Satori in yourpackage.jsonwill not override the bundled version. You must upgrade Next.js itself to 16.3.6. - Rate limiting on OG endpoints — While rate limiting reduces brute-force attempts, a single well-crafted request is sufficient for exploitation. Rate limiting provides no meaningful protection against this vulnerability.
Crowdsourced verification payload.
Run this script on any machine with access to the target application's source directory (CI runner, build server, or developer workstation). Invoke with the path to the Next.js project root: bash check_cve_2026_94545.sh /path/to/nextjs-project. No elevated privileges required — it reads package.json and node_modules only.
#!/usr/bin/env bash
# check_cve_2026_94545.sh — Detect CVE-2026-94545 (Next.js ImageResponse RCE)
# Usage: bash check_cve_2026_94545.sh /path/to/nextjs-project
# Exit codes: 0=PATCHED, 1=VULNERABLE, 2=UNKNOWN
set -euo pipefail
PROJECT_DIR="${1:-.}"
RESULT="UNKNOWN"
if [ ! -d "$PROJECT_DIR" ]; then
echo "[!] Directory not found: $PROJECT_DIR"
echo "UNKNOWN"
exit 2
fi
# Determine Next.js installed version
NEXT_VERSION=""
if [ -f "$PROJECT_DIR/node_modules/next/package.json" ]; then
NEXT_VERSION=$(grep '"version"' "$PROJECT_DIR/node_modules/next/package.json" | head -1 | sed 's/.*"version"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/')
elif [ -f "$PROJECT_DIR/package-lock.json" ]; then
NEXT_VERSION=$(python3 -c "
import json, sys
with open('$PROJECT_DIR/package-lock.json') as f:
lock = json.load(f)
pkgs = lock.get('packages', lock.get('dependencies', {}))
for key in pkgs:
if key.endswith('/next') or key == 'next':
print(pkgs[key].get('version', '')); break
" 2>/dev/null || true)
fi
if [ -z "$NEXT_VERSION" ]; then
echo "[!] Could not determine Next.js version in $PROJECT_DIR"
echo "UNKNOWN"
exit 2
fi
echo "[*] Detected Next.js version: $NEXT_VERSION"
# Parse major.minor.patch
IFS='.' read -r MAJOR MINOR PATCH <<< "$(echo "$NEXT_VERSION" | sed 's/-.*//')"
MAJOR=${MAJOR:-0}; MINOR=${MINOR:-0}; PATCH=${PATCH:-0}
# Check if version is in vulnerable range: >=16.2.0 and <16.3.6
if [ "$MAJOR" -lt 16 ]; then
echo "[+] Next.js $NEXT_VERSION is below 16.x — not affected by CVE-2026-94545."
RESULT="PATCHED"
elif [ "$MAJOR" -gt 16 ]; then
echo "[+] Next.js $NEXT_VERSION is above 16.x — likely patched."
RESULT="PATCHED"
elif [ "$MAJOR" -eq 16 ]; then
if [ "$MINOR" -lt 2 ]; then
echo "[+] Next.js $NEXT_VERSION is below 16.2.0 — not affected."
RESULT="PATCHED"
elif [ "$MINOR" -eq 2 ]; then
echo "[!] Next.js $NEXT_VERSION is in vulnerable range (16.2.x)."
RESULT="VULNERABLE"
elif [ "$MINOR" -eq 3 ] && [ "$PATCH" -lt 6 ]; then
echo "[!] Next.js $NEXT_VERSION is in vulnerable range (16.3.0-16.3.5)."
RESULT="VULNERABLE"
else
echo "[+] Next.js $NEXT_VERSION is >=16.3.6 — patched."
RESULT="PATCHED"
fi
fi
# If vulnerable, check for ImageResponse usage
if [ "$RESULT" = "VULNERABLE" ]; then
echo "[*] Checking for ImageResponse usage in source files..."
OG_USAGE=$(grep -rl 'ImageResponse\|next/og\|@vercel/og' "$PROJECT_DIR/src" "$PROJECT_DIR/app" "$PROJECT_DIR/pages" 2>/dev/null | head -20 || true)
if [ -n "$OG_USAGE" ]; then
echo "[!] ImageResponse / next/og usage found in:"
echo "$OG_USAGE" | while read -r f; do echo " $f"; done
echo ""
echo "[!] Check whether these files pass user-controlled input (searchParams, headers, etc.) into ImageResponse SVG content."
else
echo "[*] No ImageResponse / next/og usage detected in src/, app/, or pages/ directories."
echo "[*] If ImageResponse is not used, this deployment is not exploitable (but upgrading is still recommended)."
fi
fi
echo ""
echo "$RESULT"
exit $([ "$RESULT" = "PATCHED" ] && echo 0 || ([ "$RESULT" = "VULNERABLE" ] && echo 1 || echo 2))- Vercel Next.js Security Advisory (GHSA-vcvr-r3jv-pc5j)
- Satori SVG Escaping Advisory (GHSA-wx4j-mvgx-mqwp)
- Next.js Official Security Update Blog Post
- Netlify Advisory — Next.js ImageResponse Vulnerability
- HOL Guard Threat Campaign — GHSA-vcvr-r3jv-pc5j
- SecurityOnline — Next.js RCE Vulnerability CVE-2026-94545 Fixed
- W3Techs — Next.js Usage Statistics (Sep 2026)
- Nuxt OG Image Satori Fix PR
What defenders are saying.
Crowdsourced verification outputs.
Results submitted by users who ran the verification payload against their environment.