Critical Vulnerability in Next.js - Image Optimization AVIF RCE via libheif Heap Overflow
Critical heap buffer overflow in libheif chains through sharp into Next.js Image Optimization, enabling unauthenticated RCE via crafted AVIF files. Full analysis and remediation.
TL;DR: A critical heap buffer overflow in the libheif library (GHSA-g89c-p67h-r497) chains through sharp into Next.js's Image Optimization API, enabling unauthenticated remote code execution via a crafted AVIF image. CVSS 9.5 (v4). All self-hosted Next.js versions from 10.0.0 to 15.5.23 and below 16.3.3 are affected. Patch immediately to 15.5.24 or 16.3.3 — the fix disables AVIF optimization entirely until an upstream libheif fix propagates. Vercel-hosted applications are already protected.
Overview
On August 25, 2026, Vercel published an emergency security release for Next.js addressing two critical remote code execution vulnerabilities. The first — and arguably the more impactful of the two — is tracked as GHSA-2xp9-vwfh-vxw4, a supply chain vulnerability that originates not in Next.js's own code but in libheif, the open-source HEIF/AVIF decoder maintained by struktur AG.
Next.js uses the popular sharp library for its built-in Image Optimization API, which automatically resizes, converts, and serves images at optimal quality. Sharp, in turn, relies on libvips, which links against libheif for AVIF and HEIC decoding. The vulnerability — a controlled heap buffer overflow in HeifPixelImage::scale_nearest_neighbor() — allows an attacker to submit a specially crafted AVIF file to a Next.js image optimization endpoint and achieve arbitrary code execution on the server, with no authentication required.
The advisory carries a CVSS v4 score of 9.5 (Critical) with the vector 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. The attack is network-accessible, requires no privileges or user interaction, and impacts confidentiality, integrity, and availability of both the vulnerable system and subsequent systems. The only prerequisite is that the Next.js application has image optimization enabled (it is on by default) and hasn't explicitly disabled AVIF format support.
The upstream libheif vulnerability itself is tracked as GHSA-g89c-p67h-r497, scored at CVSS v3.1 9.8 (Critical), and affects all libheif versions up to and including v1.23.1. It was patched in libheif v1.23.2. The vulnerability was discovered by security researchers Harsh Jaiswal (@rootxharsh) and coordinated by Karim Rahal (@KarimPwnz). The libheif advisory confirms that the researchers achieved confirmed RCE on multiple applications.
The affected Next.js version range is extensive: every release from 10.0.0 (when Image Optimization was introduced in October 2020) through 15.5.23, and all 16.x releases before 16.3.3. Given that Next.js receives over 45 million weekly npm downloads, the potential blast radius is significant.
Technical Analysis
The root cause is a chain of four individually benign behaviors in libheif that combine into a controlled heap buffer overflow when processing a specially crafted HEIC/HEIF/AVIF file. Understanding this chain is critical because it illustrates how subtle design assumptions in low-level image processing code can become exploitable.
The Four-Step Vulnerability Chain
Step 1: Duplicate channel acceptance. The function HeifPixelImage::transfer_channel_from_image_as() moves a source pixel plane into a destination image by reassigning its channel identifier and appending it to the internal storage array (m_storage). Critically, this function does not reject a destination channel that already exists — the source code even contains a TODO comment acknowledging this gap: // TODO: check that dst_channel does not exist yet.
Step 2: First-match channel lookup. The function find_storage_for_channel() returns only the firstComponentStorage entry matching a given channel. Every downstream function — get_bits_per_pixel(), get_channel_memory(), get_width(), get_height() — therefore describes only the first Alpha plane, even when a second duplicate Alpha plane exists with different properties (bit depth, allocation size).
Step 3: Under-allocation in the scaler. The scale_nearest_neighbor() function allocates a destination Alpha plane using the bit depth reported for the first Alpha entry (8-bit). It then iterates over all entries in m_storage. When it encounters the second, duplicate Alpha plane (which is 10-bit or 12-bit), it takes the HDR code path and casts the 8-bit destination buffer to uint16_t*, writing 2 bytes per output sample into a 1-byte-per-sample allocation. This produces a heap buffer overflow where the overflow size and written values are entirely attacker-controlled.
Step 4: Identity derivation enables the exploit graph. The iden (identity-derivation) item type in ISOBMFF allows constructing a nested item reference graph. An iden item's decode_compressed_image() calls the referenced item's full decode_image(), which returns the image with its alpha channel already attached. The iden item's own decode path then attaches a second alpha channel via transfer_channel_from_image_as(). Combined with the fact that iden items bypass image size validation (their check_decoded_image_size() unconditionally returns Error::Ok), this enables the dimension mismatch that triggers the vulnerable scaler.
Attack Flow in Practice
A crafted AVIF/HEIC file contains five ISOBMFF items arranged to produce the overflow:
| Item | Type | Size | Role |
|---|---|---|---|
| 1 | hvc1 | 64×64 (8-bit) | Color image with auxiliary alpha → Item 2 |
| 2 | hvc1 | 64×64 (8-bit) | Alpha aux of Item 1 |
| 3 | iden | 64×64 (declared) | Identity derivation → Item 1; has own alpha → Item 4 |
| 4 | hvc1 | 64×64 (10-bit) | Alpha aux of Item 3 |
| 5 | hvc1 | 128×128 (8-bit) | Primary item; alpha → Item 3 |
When the primary item (Item 5) is decoded, Item 3's image ends up with two Alpha planes — one at 8-bit from Item 1's alpha, one at 10-bit from Item 4. The declared ispe dimension mismatch between Item 3 (64×64) and Item 5 (128×128) triggers scale_nearest_neighbor(), which allocates 16,384 bytes (128×128×1) for the Alpha plane but writes 32,768 bytes (128×128×2) through the HDR branch — an overflow of approximately 16,384 bytes past the allocation boundary.
In the context of Next.js, an attacker submits this crafted AVIF file to the Image Optimization API endpoint (typically /_next/image?url=...&w=...&q=...). The image optimization pipeline passes it to sharp, which calls libheif's heif_decode_image(), triggering the overflow on the server.
Business Impact
The business implications of this vulnerability are substantial due to several factors.
Massive attack surface. Next.js is the most widely used React framework with over 45 million weekly npm downloads. The Image Optimization API is enabled by default, meaning any self-hosted Next.js application that hasn't explicitly disabled it is a potential target. The vulnerability spans six years of releases (10.0.0 through current), meaning even legacy deployments are at risk.
Unauthenticated, no-interaction RCE. An attacker needs only network access to the Next.js server and the ability to send a crafted AVIF file to the image optimization endpoint. No authentication, no user interaction, no special configuration is required from the target. This dramatically lowers the bar for exploitation.
Supply chain depth. The vulnerability sits three layers deep in the dependency chain (Next.js → sharp → libvips → libheif), making it invisible to teams who only audit their direct dependencies. This is a textbook example of why transitive dependency management and software composition analysis are critical.
Platform and hosting considerations. Vercel has confirmed that applications hosted on its managed platform are protected — Vercel disabled AVIF optimization across its managed Image Optimization service immediately. Cloudflare responded with an emergency WAF release on August 26, 2026. However, self-hosted deployments on any cloud provider, on-premise infrastructure, or platforms like Netlify (which deferred to the upstream fix) require manual patching.
Regulatory exposure. For organizations subject to PCI-DSS, SOC 2, or similar compliance frameworks, an unpatched critical RCE vulnerability in a customer-facing web application represents a compliance gap that auditors will flag.
Exploitation Status
As of August 27, 2026, the exploitation landscape for this vulnerability is as follows:
Public PoC exists for libheif. The upstream libheif advisory (GHSA-g89c-p67h-r497) includes a complete proof-of-concept Python script (gen_poc.py) that generates a crafted HEIC file triggering the heap buffer overflow. The PoC requires Python 3 and ffmpeg with libx265. The researchers confirmed they achieved RCE on multiple applications using this vulnerability.
No confirmed in-the-wild exploitation (yet). Neither Vercel, CISA, nor any threat intelligence vendor has reported active exploitation of this specific vulnerability at the time of writing. However, given the availability of a public PoC and the massive attack surface, exploitation in the wild is likely a matter of when, not if.
No CVE assigned. As of publication, no CVE identifier has been assigned to either the Next.js advisory (GHSA-2xp9-vwfh-vxw4) or the underlying libheif vulnerability (GHSA-g89c-p67h-r497). CVE assignment is pending.
Not yet in CISA KEV. The vulnerability has not been added to CISA's Known Exploited Vulnerabilities catalog.
WAF protections rolling out. Cloudflare published an emergency WAF managed ruleset release on August 26, 2026 specifically targeting this vulnerability, suggesting the industry considers exploitation imminent.
Reproduction Steps
⚠️ Disclaimer: These steps are provided for authorized security testing and educational purposes only. Unauthorized exploitation is illegal and unethical. Always obtain written permission before testing.
The upstream libheif advisory provides a complete proof-of-concept. Below is a summary of how it applies in the Next.js context.
Prerequisites
- A self-hosted Next.js application running a vulnerable version (10.0.0 ≤ version < 15.5.24, or < 16.3.3)
- Image Optimization API enabled (default configuration)
- Python 3.6+, ffmpeg with libx265 (for PoC generation)
Steps
- Generate the crafted HEIC file using the
gen_poc.pyscript from the libheif advisory. This produces apoc.heicfile with the nested iden/auxl item graph. - Convert or rename the file to AVIF format — the ISOBMFF container structure is shared between HEIC and AVIF. The file can be served with an
.avifextension orimage/avifcontent type. - Submit the file to the Next.js Image Optimization endpoint. If the application accepts external image URLs, host the crafted file and request it through
/_next/image?url=<attacker-url>&w=128&q=75. If the application processes uploaded images through the optimization pipeline, upload the file directly. - Observe the server crash or code execution. Under ASan, the overflow triggers an immediate detection report. Without ASan, the overflow corrupts heap memory — the attacker controls the overflow extent (via output geometry) and the values written (via HEVC bitstream content).
Expected Result
The server process either crashes (denial of service) or, with a carefully constructed payload, achieves arbitrary code execution. The libheif advisory explicitly states the overflow size and written values are attacker-controlled.
Detection
Version Checking
Determine your Next.js version:
npx next --version
# or check package.json
cat node_modules/next/package.json | grep '"version"'
Any version >= 10.0.0 and < 15.5.24, or any 16.x version < 16.3.3, is vulnerable.
Check your sharp and libheif versions:
node -e "console.log(require('sharp').versions)"
If heif shows a version ≤ 1.23.1, the underlying libheif is vulnerable.
Log Signatures
Monitor server logs for requests to the image optimization endpoint with AVIF content:
- Requests to
/_next/imagewithurlparameters pointing to external domains serving.aviffiles - Unusual server crashes or out-of-memory errors in the image processing pipeline
- Segmentation faults in sharp/libvips/libheif worker processes
Jsmon Detection
Organisations using Jsmon's EASM platform can leverage the technology fingerprinting module to identify exposed Next.js instances across their external attack surface. Jsmon's JavaScript analysis engine can detect Next.js version signatures in /_next/ asset paths and build manifests, flagging instances running vulnerable versions for prioritised remediation.
Mitigation & Remediation
Immediate Actions
- Apply WAF rules. If you use Cloudflare, their emergency WAF release from August 26, 2026 includes managed rules for this vulnerability. For other WAFs, consider blocking or inspecting requests to
/_next/imagethat involve AVIF content. - Restrict the Image Optimization API. If your application doesn't need to optimize external images, restrict the
images.remotePatternsconfiguration to only trusted domains, reducing the attack surface for attacker-controlled image URLs.
If you cannot upgrade immediately, disable AVIF image format support in your next.config.js:
module.exports = {
images: {
formats: ['image/webp'], // Remove 'image/avif'
},
};
Upgrade Next.js to 15.5.24 or 16.3.3. This is the primary and most effective remediation. The patched versions disable AVIF optimization entirely — AVIF images are served as-is without passing through the vulnerable libheif decoding path.
npm install [email protected] # for 15.x deployments
npm install [email protected] # for 16.x deployments
Long-Term Recommendations
- Monitor for the upstream libheif fix. Vercel has already opened PRs to re-enable AVIF optimization once sharp ships with libheif ≥ 1.23.2 (see #97949 and #97954). Track these for the timeline on AVIF re-enablement.
- Implement Software Composition Analysis (SCA) to catch transitive dependency vulnerabilities like this one. Tools that trace vulnerabilities through deep dependency chains would have flagged this issue.
- Review your image processing pipeline. If your application processes user-uploaded images through any path that touches libheif (not just Next.js — ImageMagick, libvips, and other processors are also affected), ensure the underlying library is updated.
Jsmon Recommendation
Organisations using Jsmon's External Attack Surface Management platform can identify exposed Next.js instances running vulnerable versions across their entire external footprint using the technology fingerprinting and JavaScript analysis modules. Continuous monitoring ensures new deployments and instances are detected as they appear, reducing the window of exposure for supply chain vulnerabilities like GHSA-2xp9-vwfh-vxw4.
Timeline
| Date | Event |
|---|---|
| 2026-08-25 | Vulnerability disclosed; libheif v1.23.2 released with fix (GHSA-g89c-p67h-r497) |
| 2026-08-25 | Vercel moves Next.js security release forward from Aug 26 to Aug 25 |
| 2026-08-25 | Next.js 15.5.24 and 16.3.3 published with AVIF optimization disabled |
| 2026-08-25 | GHSA-2xp9-vwfh-vxw4 published by @eps1lon (Sebastian Silbermann) |
| 2026-08-25 | Vercel confirms hosted applications are protected (AVIF optimization disabled platform-wide) |
| 2026-08-26 | Cloudflare publishes emergency WAF managed ruleset release |
| 2026-08-26 | PRs opened to re-enable AVIF with runtime libheif version guard (#97949, #97954) |
| 2026-08-27 | CVE assignment pending |
References
- Next.js Advisory — GHSA-2xp9-vwfh-vxw4
- libheif Advisory — GHSA-g89c-p67h-r497 (Heap Buffer Overflow in scale_nearest_neighbor)
- Next.js August 2026 Security Release Blog
- Vercel Changelog — August 2026 Security Release
- Cloudflare WAF Emergency Release — 2026-08-26
- libheif v1.23.2 Release Notes
- Cyber Security News — Critical Next.js Vulnerabilities
- SecurityOnline — Next.js RCE Flaw Hits 45M Downloads
- Netlify Changelog — Next.js Security Release (August 2026)
- Harsh Jaiswal (@rootxharsh) — Finder
- Karim Rahal (@KarimPwnz) — Coordinator