Attacker-controlled bytes written past the buffer: 58 bytes (Source: fortbridge.co.uk research (Sept. 28, 2026))
A lab result, and what it does and does not say
Behind an "upload a photo" button sits native code that budget conversations rarely reach. A writeup from fortbridge.co.uk, dated September 28, 2026, examines CVE-2026-32740, a heap overflow in libheif's HeifPixelImage::copy_image_to(), the routine that assembles decoded HEIF or AVIF tiles into a single grid image. In the lab's Next.js stack, sharp relies on native libvips and libheif code packaged with it to process AVIF files.
The scope matters. The flaw is in libheif, not in Next.js. The remote code execution result came from a test application the researchers built and describe as deliberately vulnerable, so it says nothing directly about a live deployment. The vulnerable code runs when the server decodes a file, for example when the application opens a stored image to convert it. Saving the upload is a separate step.
How a rounding mismatch becomes a write
libheif keeps a decoded image as separate planes: brightness (Y) and two colour-difference planes (Cb and Cr). In the 4:2:0 format, the colour planes have half the rows and columns of the brightness plane, with odd values rounded up. According to fortbridge, the code rounds the destination row up and, separately, rounds the copy height up. The bounds check on the height does not account for the rounded row.
The malformed image is built from four tiles, each 33 pixels tall, on a canvas 132 pixels high. The last tile pushes the copy one chroma row past the end of the allocation. On a canvas 116 pixels wide, that row is 58 bytes, and the malformed tile supplies every one of them. The attacker therefore controls the contents of one 58-byte block just beyond the buffer.
From a crash to running code
Fortbridge says a write of this kind normally just crashes the process. Reaching code execution took a multi-step chain against a lab with two endpoints. One stores whatever file is uploaded. The other takes the name of a stored file, has sharp convert it to a PNG, and returns that PNG to the caller.
First, a crafted image leaks memory pointers through the pixels of the returned PNG, revealing where libvips was loaded despite address randomization. Next, the overflowing image corrupts a link in the map libheif uses to find image planes, so a later lookup lands on a forged entry built from image pixels. That entry redirects a memory-copy call to a loader routine inside libvips, which opens a shared object the attacker uploaded. The proof-of-concept payload ran the command /usr/bin/id.
One lab condition carries a lot of weight. The upload handler was built to be lax: it accepted a compiled Linux shared library (an ELF file) and stored it as x.jpg, a name that looks like a photo. The short name matters because the payload has only 16 bytes for the library path.
The chain is also tightly fitted. The exploit relies on hardcoded values tied to a specific native stack, and it needs a fourth leaked pointer to tell the tested Ubuntu and Debian profiles apart. It proceeds "only when all four pointers resolve to the same base". Fortbridge adds that a different libvips version or build would need additional profiling.
Where the difficulty sat
This case supports a narrow observation: the risk did not sit in the JavaScript a team writes and reviews. It sat in native decoding code underneath the application. Choosing a modern framework does not change what the image library beneath it does with an untrusted file. That is WebPulse's reading of one lab proof of concept, not a measure of how many production sites are exposed, and the source offers no such figure.
What the writeup says about mitigation, and what it does not
The portion of the writeup we reviewed offers no remediation guidance. Its one relevant remark concerns the lab's permissive upload route: a production system that verifies file signatures, renames files when saving them, or keeps uploads in separate object storage might deny the attacker the chance to place a library on disk. The decoding flaw would be untouched. That remark describes a weakness in the lab, not a fix.
Our own analysis follows from it. Validating what a file really contains, assigning storage names on the server side, and isolating uploads are sensible questions for any team. Each addresses one link in this chain, and none patches the flaw. The source as provided does not say whether a fixed version is available, so patch status has to be confirmed with the maintainers and vendor advisories.
Questions for the team that owns this
Which upload-facing routes in our stack call sharp, libvips or another native image library, and do any of them decode AVIF or HEIF files? Do we validate uploads by their actual content, not their filename or declared media type? Are uploads stored under generated names, ideally in isolated storage? Have we confirmed, with the maintainers or vendor advisories, whether a fix for CVE-2026-32740 exists, and where it is deployed across every service that touches user-submitted images?
Fortbridge's chain needed exact binary fingerprints, leaked addresses and a forged internal data structure. The entry point, though, was the most ordinary feature on the page. In this lab, the upload button was the visible surface, and the bug sat one dependency deeper.
Produced by the WebPulse Newsroom with AI assistance from the original reporting credited below, and checked against that source by our editorial review. How we use AI.
Original reporting: fortbridge.co.uk.





