Posted in

Warning: Massive New PHP Memory Flaw Exposes App Server Data via JPEG Uploads

On May 16, 2026, a critical threat advisory was disclosed exposing severe memory-safety vulnerabilities within the native core image-processing extensions of the PHP programming language.

Discovered by security researcher Nikita Sveshnikov of Positive Technologies, the flaws expose public-facing web applications to remote information disclosure and severe heap corruption.

The security defects are located inside the widely deployed getimagesize() and iptcembed() functions within PHP’s ext/standard extension. Because these functions are the industry standard for processing image metadata—handling everything from extracting EXIF coordinates to embedding authorship tags—the attack surface directly impacts Content Management Systems (CMS), webmail clients, image Content Delivery Networks (CDNs), and any enterprise web application featuring a public user-upload endpoint.


The Exploit Mechanics: Deconstructing the Two Attack Paths

The disclosure outlines two distinct architectural failures within PHP’s memory management abstraction layers, each weaponizing a different phase of JPEG structural parsing.

1. The Chunk Read Pointer Override (CVE-2025-14177)

The first vulnerability, holding a CVSS score of 6.3, targets how the internal helper function php_read_stream_all_chunks() processes JPEG Application (APP) metadata segments under multi-chunk reading mode (such as when images are ingested via stream wrappers like php://filter).

When an application calls getimagesize(), the function allocates a memory block using PHP’s internal emalloc mechanism, which returns uninitialized memory addresses still containing scraps of data from previously executed server processes.

Plaintext

Malicious JPEG Upload ➔ getimagesize() Allocates Uninitialized Memory ➔ Loop Reads Multi-Chunks ➔ Pointer Fails to Advance ➔ New Chunks Overwrite Buffer Start ➔ Untouched Buffer Tail Leaks Raw Process Memory

The system is designed to append sequential data chunks into this buffer as it reads the image. However, a logic flaw prevents the system from incrementing the buffer’s destination pointer after each individual chunk read.

As a result, every subsequent chunk read from the JPEG file continuously overwrites the beginning of the allocated memory space, leaving the trailing section of the buffer completely untouched and uninitialized.

When the function completes, it packages this buffer and returns it to the application within the $info['APPn'] array. Because the tail of the buffer was never overwritten by the image data, it contains raw fragments of uninitialized heap memory.

By crafting a JPEG containing a large APP1 segment designed to split across multiple standard 8,192-byte stream chunks, an attacker can extract sensitive system data—such as environment variables, database credentials, or active session tokens—sprayed across the server’s memory space.

2. The “Measure Once, Read Forever” Buffer Overflow

The second flaw targets the iptcembed() function, which is utilized to inject binary International Press Telecommunications Council (IPTC) metadata directly into JPEG structures. This vulnerability manifests as a classic heap buffer overflow driven by a “Time-of-Check to Time-of-Use” (TOCTOU) race condition and an inadequate file-stat validation design.

When processing an input stream, iptcembed() relies on a single native fstat() call to determine the source file size, allocating an equivalent output buffer (spoolbuf) based entirely on that single value.

The fatal flaw occurs when the function is fed non-standard file streams, such as named pipes (FIFOs), network sockets, or UNIX pipes:

  • For these dynamic stream interfaces, fstat() returns an explicit file size of 0.
  • PHP blindly accepts this value, allocating an drastically undersized memory buffer.
  • The system then switches into an unmonitored php_iptc_read_remaining mode, continuously copying the incoming stream into the buffer until it encounters an End-of-File (EOF) marker.

Because the internal pointer mapping function php_iptc_get1() advances through the target memory space without checking the boundary lines of the allocated spoolbuf_end wall, a malicious payload can continuously write bytes past the buffer boundaries, corrupting the heap and allowing for potential remote code execution.


Proof-of-Concept Validation

Researchers successfully demonstrated the viability of both exploit paths using minimalistic, weaponized JPEG payloads:

  • For the Leak Exploit: The testing team performed heap spraying to fill target memory zones with a specific string validation marker (LEAK-MARKER-123!), passed a tailored multi-chunk JPEG through a php://filter stream, and successfully read the secret tracking string out of the resulting getimagesize() array output.
  • For the Buffer Overflow: The exploit utilized a dual-terminal setup routing a crafted JPEG structure followed by 8MB of arbitrary binary data through a local named pipe (FIFO). Because the system registered the pipe size as zero, the processing run instantly triggered an out-of-bounds heap write, caught and validated via AddressSanitizer (ASan).

Affected Version Matrix

The vulnerabilities impact multiple active and legacy development branches of the PHP runtime ecosystem. Systems running versions deployed prior to the official upstream patch rollout on May 14, 2026, are actively vulnerable:

PHP BranchVulnerable Version RangeSafe Patched Release
PHP 8.1All versions prior to 8.1.348.1.34
PHP 8.2All versions prior to 8.2.308.2.30
PHP 8.3All versions prior to 8.3.298.3.29
PHP 8.4All versions prior to 8.4.168.4.16
PHP 8.5All versions prior to 8.5.18.5.1

Remediation & Patch Blueprint

To permanently eliminate these exploit paths, PHP’s core engineering team has refactored the underlying extension logic:

  1. Pointer Fix: For CVE-2025-14177, the php_read_stream_all_chunks() loop was updated to explicitly advance the memory destination address after every successful chunk iteration (buffer += read_now), ensuring data is safely appended rather than stacked destructively.
  2. Boundary Bounds Enforced: For the iptcembed() overflow, developers introduced a strict boundary validation check into the php_iptc_get1() and php_iptc_put1() sub-routines, forcing the parser to safely abort and return EOF the exact moment the write pointer hits the maximum boundary limit of spoolbuf_end.

Immediate Strategic Directives for Security Teams:

  • Run Container Inventory: Scan all live application containers, Kubernetes pods, and production environments to flag out-of-date PHP runtimes.
  • Prioritize Edge Assets: Focus patching schedules immediately on high-exposure edge vectors, such as user avatar upload systems, automated gallery thumbnailers, and attachments processors within internal ticketing systems.
  • Implement Temporary WAF Rules: Where immediate runtime updates are restricted by legacy dependencies, configure Web Application Firewalls (WAFs) to inspect incoming multi-part form uploads, blocking or stripping non-standard, bloated APP and IPTC metadata blocks from JPEG headers before they hit the backend PHP processing engine.

Leave a Reply

Your email address will not be published. Required fields are marked *