Malicious HEIC Images Can Trigger Remote Code Execution on WordPress Servers: A Deep Dive into the libheif Exploit Chain

The CyberSec Guru

libheif Vulnerability HEIC Image RCE in WordPress

If you like this post, then please share it:

Buy me A Coffee!

Support The CyberSec Guru’s Mission

🔐 Fuel the cybersecurity crusade by buying me a coffee! Why your support matters: Zero paywalls: Keep the main content 100% free for learners worldwide.

“Your coffee keeps the servers running and the knowledge flowing in our fight against cybercrime.”☕ Support My Work

Buy Me a Coffee Button

For over a decade, web application security has mostly treated image uploads as low risk. Administrators sanitize PHP scripts and block executable binaries, but image files are usually assumed to be inert data. The web’s shift to high-efficiency photo formats like HEIC, HEIF, and AVIF has forced servers to lean on complex native C++ parsing libraries, and when those libraries have memory corruption bugs, a profile picture upload can become a remote code execution weapon.

In October 2026, security researchers at Fortbridge published an analysis of a fully weaponized exploit chain that turns a standard WordPress Media Library upload into server side code execution. It chains a heap buffer overflow in libheif (GHSA-x8r2-mggj-j6wr, CVE-2026-47178) with an ASLR bypass hidden inside WordPress-generated JPEG thumbnails, giving attackers control of the underlying PHP-FPM process.

This piece walks through the libheif RCE chain: how the overflow works, how memory addresses leak through pixel data, and what to do about it.

The illusion of safe media parsing

When a user uploads a modern smartphone photo (HEIC, or the open AVIF format) to a WordPress site, PHP doesn’t parse the image itself. WordPress hands it to ImageMagick, which delegates HEIC/HEIF decoding to libheif.

PHP is memory-managed and largely immune to classic buffer overflows. libheif is not. It’s written in C++ and allocates buffers for color planes, pixel data, and compression directly in memory. A malformed file that tricks the decoder into miscalculating a buffer boundary causes memory corruption, and that’s a direct bridge from an unauthenticated or low-privileged web request into the operating system’s memory space.

It gets worse because image processing runs inside the same PHP-FPM worker pool that executes the site’s core logic. Code execution inside the ImageMagick decoding process inherits the web server’s permissions (typically www-data), which means immediate access to database credentials and config files, and a foothold for moving deeper into the network.

Malicious HEIC RCE
Malicious HEIC RCE

The root cause: a heap overflow in uncompressed decoding

The core vulnerability sits in how libheif handles uncompressed image data in the mixed-interleave YCbCr color path. GHSA-x8r2-mggj-j6wr, tracked as CVE-2026-47178, affects libheif versions 1.18.0 through 1.23.2. Alex Thomas and the Wordfence Argus team found the heap buffer overflows in the uncompressed image decoder in late 2026.

Images are made of planes, Luma, Cb, and Cr, and the decoder reads the file header to figure out each channel’s bit depth, then allocates exactly enough heap memory to hold it.

The bug shows up when a crafted HEIC file declares mismatched bit depths for the paired chroma channels, say Cb at 16-bit and Cr at 8-bit. Here’s what happens:

libheif allocates the Cr buffer assuming one byte per sample. During decoding, the mixed-interleave loop processes both channels together, but a stride calculation bug applies the 16-bit width meant for Cb to both channels’ writes. So the decoder advances two bytes at a time into a buffer sized for one, and after a few dozen rows it runs past the heap boundary it was given.

📬 Stay Ahead of Cyber Threats

Get the latest cybersecurity news, critical vulnerabilities, threat intelligence, tutorials, and exclusive giveaways delivered straight to your inbox. No spam. Unsubscribe anytime.

Subscribe to the Newsletter →

The result is a file-controlled heap overflow: attacker bytes spill into adjacent allocations, which in a C++ application often hold object metadata, channel vectors, and virtual table pointers (vptr).

The ASLR bypass: leaking memory through pixels

A heap overflow by itself usually isn’t enough for reliable RCE on modern Linux. ASLR randomizes where libraries like libc and libheif sit in memory each time a process starts, so without knowing those addresses an attacker can’t point an overwritten vptr anywhere useful.

The old way to beat ASLR was a second info-leak bug that printed addresses straight into an HTTP response. Fortbridge did something different: it pulls memory addresses out of the pixels of a generated JPEG thumbnail.

GHSA-2jg2-4ch7-h545: derived-item and plane-geometry flaws

This part leans on a second info disclosure bug (GHSA-2jg2-4ch7-h545) in how libheif handles derived images and plane geometry. An attacker crafts an “identity-derived” image that claims dimensions bigger than its real backing memory plane. When libheif crops it, it reads past the real allocation and pulls in raw, uninitialized, or adjacent heap bytes.

Hiding pointers in plain sight

WordPress generates several resized thumbnails from the malicious HEIC upload, converting the decoded data into lossy JPEG. The raw memory bytes leaked by the crop bug end up rendered as pixel color data.

JPEG compression adds noise, so reading raw memory bytes straight off a JPEG wouldn’t normally be reliable. Fortbridge got around this by expanding each leaked byte into a uniform 8×8 block of identical pixels, then reconstructing 64-bit pointers by downloading the generated JPEG and taking the median color value of each block.

The leaked pixels give four kinds of evidence: glibc arena pointers (for resolving libc’s page-aligned base address), thread-arena and decoder pointers (for mapping the Ubuntu heap layout), native-library pointer pairs (for fingerprinting the exact libheif build), and on Debian, adjacent MagickCore callback pointers such as CompareSplayTreeString and RelinquishMagickMemory, used to calculate ImageMagick’s live base address.

The WordPress Media Library effectively becomes an oracle: it decodes the hostile file, embeds its own memory layout into a JPEG, and hands that back to the attacker.

From upload to RCE

The Fortbridge chain combines web application logic, image format fuzzing, allocator analysis, and C++ object layout manipulation. It requires an authenticated WordPress user with upload_files capability, so an Author, Editor, or Administrator.

Fingerprinting and profile selection

The exploit uploads the disclosure images, downloads the resulting JPEGs, decodes the pixel data, and extracts pointers. It doesn’t guess the OS from HTTP headers or banners; it needs a complete, consistent native-module pattern from the pixels. If the pointers don’t resolve to a single page-aligned module base matching a known profile, it aborts rather than guess.

Fortbridge validated the chain against two stacks:

  • Ubuntu 26.04: WordPress 7.1.1, PHP-FPM 8.5.4, ImageMagick 7.1.2.18, libheif 1.21.2, glibc 2.43.
  • Debian 13: WordPress 7.0, PHP-FPM 8.4.24, ImageMagick 7.1.1.43, libheif 1.19.8, glibc 2.41.

PHP-FPM worker exhaustion and calibration

PHP-FPM spawns a pool of worker children from a master process. ASLR is set when the master starts, so all children share the same library base addresses, though thread arenas can still vary.

To make sure the leaked addresses match the worker that runs the payload, the exploit needs to control scheduling. It sends seven slow, valid HEIC uploads to tie up seven workers in an eight-child pool, then sends a shorter, gated request that forces the eighth worker to handle address recovery, heap calibration, and the final trigger.

Overwriting the vptr

With the memory layout known, the exploit builds the trigger image using the unci (uncompressed) box type to set off the heap overflow described earlier.

C++ objects with virtual functions keep a vptr at the start of their memory layout, pointing to a vtable of function addresses. When libheif‘s decoder finishes and enters teardown, it makes a virtual call.

The overflow is calculated to land right on that vptr, redirecting it to a fake dispatch structure the attacker has already written into writable memory, often the ImageMagick MagickCore data segment or a predictable libc arena. That structure points to a do_system call site in libc along with the attacker’s shell command, for example id > /var/www/html/rce-proof.txt. When teardown runs, the hijacked vptr makes the server execute that command as www-data.

How reliable is it, and who’s exposed

In testing, the Ubuntu profile got code execution in 6 of 8 fresh PHP-FPM parent processes (75%), and the Debian profile hit 22 of 24 (91.7%).

Worth separating crash from RCE here. A malformed HEIC file will often just segfault the ImageMagick worker, giving a 503. That’s a sign the bug exists, nothing more. Fortbridge only counts a success when a follow-up GET to the proof path returns 200 with the executed command’s output, like uid=33(www-data).

Who is actually vulnerable

The baseline exploit needs an authenticated user with upload_files, which in a default install limits things to Authors and up. But the real exposure is wider because of the plugin ecosystem:

Frontend upload plugins, form builders, profile photo uploaders, support ticket systems, often let unauthenticated guests or Subscribers upload images, and if those plugins hand the file to the WordPress Media Library or ImageMagick for resizing, the authentication requirement disappears.

Shared hosting setups can see cross-tenant contamination if PHP-FPM pools or image daemons share resources without strict sandboxing.

And libheif isn’t WordPress-specific. It’s used across the Linux ecosystem, including Next.js via the sharp library, GIMP, and various thumbnail generators, so any app that processes untrusted HEIC/AVIF through a vulnerable build is potentially at risk.

Mitigation and hardening

WAFs alone won’t catch this. They’re built to flag SQL injection or XSS patterns in text, not malformed binary structures inside HEIC unci boxes.

Patch libheif. The heap overflow (GHSA-x8r2-mggj-j6wr) is fixed in 1.23.3, and the info disclosure bug (GHSA-2jg2-4ch7-h545) in 1.23.2. Check that the OS package update actually reaches the library ImageMagick links against; a statically linked or locally compiled libheif won’t get touched by apt upgrade.

Turn off coders you don’t need. If your app has no real need to accept HEIC, HEIF, or AVIF, block ImageMagick from processing them in policy.xml (commonly at /etc/ImageMagick-6/policy.xml or /etc/ImageMagick-7/policy.xml):

<!-- Disable potentially dangerous modern image coders if not required -->
<policy domain="coder" rights="none" pattern="HEIC" />
<policy domain="coder" rights="none" pattern="HEIF" />
<policy domain="coder" rights="none" pattern="AVIF" />

With rights="none", ImageMagick rejects these formats before they ever reach libheif.

Sandbox the processing. Image decoding shouldn’t share memory space or privileges with the core app. Route uploads to an isolated, disposable container with no access to the database, environment variables, or internal network. Use AppArmor or SELinux to restrict the ImageMagick process to read-only access on the upload directory and write access on the media folder, nothing else. And make sure your web server config blocks PHP/CGI execution inside /wp-content/uploads/; it won’t stop the memory corruption, but it closes off the easiest path to a persistent web shell afterward.

Watch for the signs. A spike in PHP-FPM worker crashes tied to upload traffic, intermittent 503s after modern image uploads, stray files like rce-proof.txt in the web root (the marker Fortbridge’s Debian profile uses), or rapid sequential uploads of identically sized .heic files from one IP, which looks like the worker-exhaustion phase of the attack.

Where this leaves media parsing security

The OWASP Top 10 doesn’t really cover the native attack surface sitting behind most web apps. As the web keeps moving from JPEG and PNG toward HEIC and AVIF, reliance on native C/C++ decoders is only going to grow.

What this research shows is that a WordPress media upload form, about as ordinary an entry point as exists, can be turned into heap feng shui, an ASLR bypass via pixel steganography, and a hijacked C++ vtable. Validating file extensions and MIME types isn’t enough. Treat user-supplied media as potentially hostile binaries, isolate the processing, and keep the native libraries patched.

FAQ

Does this require an authenticated user? By default, yes, upload_files capability (Author or above). But plugins that let unauthenticated guests submit avatars, support attachments, or similar through the native image pipeline widen that considerably.

Does blocking HEIC/HEIF/AVIF protect me? If your site blocks those formats at the application level and policy.xml rejects the coders, you’re not exposed to this specific chain, since it depends on the server actually attempting to decode uncompressed HEIC data.

How do I check if I’m vulnerable? Check your installed libheif version (apt list --installed | grep libheif or dpkg -l | grep libheif). Anything before 1.23.3 has the heap overflow. Also check whether ImageMagick still has HEIC delegates loaded.

Why didn’t my WAF catch this? WAFs look for known web attack signatures like SQLi or XSS in HTTP payloads. This exploit relies on crafted binary structures inside HEIC’s unci and iden boxes that trigger memory corruption in a C++ library, nothing that resembles a typical web attack pattern.

Is a crash the same as RCE? No. A malformed file can segfault the worker and produce a 503, which indicates the vulnerability but not exploitation. Actual RCE needs the heap overflow aligned precisely enough to hijack the vptr and run a system command, which is what Fortbridge’s ASLR bypass via pixel leakage makes possible.

Buy me A Coffee!

Support The CyberSec Guru’s Mission

🔐 Fuel the cybersecurity crusade by buying me a coffee! Your contribution powers free tutorials, hands-on labs, and security resources.

Why your support matters:
  • Writeup Access: Get complete writeup access within 12 hours
  • Zero paywalls: Keep the main content 100% free for learners worldwide

Perks for one-time supporters:
☕️ $5: Shoutout in Buy Me a Coffee
🛡️ $8: Fast-track Access to Live Webinars
💻 $10: Vote on future tutorial topics + exclusive AMA access

“Your coffee keeps the servers running and the knowledge flowing in our fight against cybercrime.”☕ Support My Work

Buy Me a Coffee Button

If you like this post, then please share it:

Exploits

Discover more from The CyberSec Guru

Subscribe to get the latest posts sent to your email!

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Discover more from The CyberSec Guru

Subscribe now to keep reading and get access to the full archive.

Continue reading