Leaked Ahead of Time: In-the-Wild Exploits Outran the Patch by Four Days
On October 21, 2026, the PHP development team issued emergency updates addressing two critical remote code execution (RCE) flaws: CVE-2026-109618 and CVE-2026-109619. Both vulnerabilities carry a CVSS v4.0 score of 9.2. Official fixes were rolled out across PHP 8.2.35, 8.3.36, 8.4.27, and 8.5.12. In an extraordinary move, the security team also backported source-level patches to long-unsupported branches, including PHP 7.4, 8.0, and 8.1.
Standard coordinated vulnerability disclosure assumes patches reach defenders before weaponized exploits reach the wild. With PHP2Shell, that mechanism collapsed entirely. Days prior to the release, Huntress published an early alert titled “Leaked Critical PHP Vulnerabilities,” warning that technical details had leaked through backchannels. In an unprecedented move, PHP maintainers broadcast Announcement #509 on php.announce urging systems administrators worldwide to prepare in advance. Ars Technica covered the anomalous alert, noting that maintainers blowing the whistle early signified the disclosure process was spiraling out of control.
Threat actors did not wait. Datadog Security Labs had already engineered a functional exploit independently before the public disclosure. AWS Threat Intelligence confirmed via its MadPot honeypot network that live exploitation attempts had been captured as early as October 17—a full four days before the official release. Attackers were actively probing exposed instances across the public internet well before defenders received advisory notes.
Security firm Sansec issued an urgent warning: automated wide-scale internet attacks would materialize within fifteen minutes of patch availability. By October 21, Datadog cited telemetry from Patchstack confirming active wild exploitation and indiscriminate internet-wide scanning campaigns underway. Attackers and defenders gained access to patch diffs simultaneously, reducing the standard upgrade and remediation window to zero.
Figure: Overview of PHP2Shell impact scope and attack chains released by Datadog Security Labs. Source: Datadog Security Labs
Commands Executed Before App Logic: Shells Spawned in Parser Cleanup
Most web application security models rely heavily on API gateways, routing authentication, and source code audits. In Datadog Security Labs’ technical reproductions, PHP2Shell bypassed every application-level defense layer. Using an environment configured with PHP 8.5.11, Apache prefork with mod_php, and standard limits (memory_limit=16M, post_max_size=64M), an unauthenticated attacker could take over the host with a single crafted HTTP POST request.
The exploit triggers at the C runtime level of the PHP interpreter itself. When a malicious payload arrives, it deliberately induces an unhandled parsing error before the execution flow reaches any application script. During PHP’s internal cleanup routine for failed requests, the runtime executes shell commands injected through the exploit payload. Even on a server hosting nothing more than a static script printing “Hello World”, the entire system is compromised at the exact moment parsing fails.
This vector punches through virtually every standard deployment model. According to Huntress advisories and technical trackers, installations spanning PHP 5 through PHP 8 are vulnerable. Impacted runtimes encompass Apache mod_php, legacy php-cgi, high-concurrency production workhorse PHP-FPM, next-gen FrankenPHP, and LiteSpeed. Application firewalls and middleware authentication never get the opportunity to evaluate the request.
Figure: Call trace showing the malicious request triggering parser cleanup routines that execute system commands. Source: Datadog Security Labs
Counter Updated Before Allocation: Deconstructing the Dual-CVE Flaws
The two CVEs exploit distinct architectural oversights across the HTTP request lifecycle. CVE-2026-109618 stems from an error-handling routine that improperly trusts invalid memory structures following an allocation failure. The vulnerable code sits inside Zend Engine core function _zend_hash_str_add_or_update_i(). When inserting key-value pairs into a hash table, the engine increments the bucket counter prior to allocating memory for the key string.
If allocating the key exceeds memory_limit, the Zend Engine immediately raises a fatal error. At this juncture, the internal counter already accounts for the unallocated bucket node, which contains uninitialized dirty bytes from previous heap operations. The subsequent cleanup process misinterprets these leftover bytes as valid variable definitions and attempts to destroy them. By controlling residual memory, attackers divert control flow to system(). Even in PHP 8.5.12, the counter is still updated before allocation; the official fix remedies the cleanup error path so aborted allocations no longer leave half-initialized table entries.
The companion flaw, CVE-2026-109619, takes advantage of cross-request state pollution within persistent worker processes. Under PHP 8.5, fatal error backtraces in mod_php can directly lead to arbitrary command execution. More broadly in multipart file uploads, session and decoder states left over from fatal errors leak across subsequent requests. Because session.upload_progress.enabled is enabled by default in many distributions, this mechanism runs silently in the background without any application calling session_start().
Successfully triggering CVE-2026-109619 requires consecutive malicious requests to land on the exact same worker process. In pooled multi-process architectures or high-traffic clusters, the single-hit probability is diluted. However, this merely introduces a statistical barrier—it does not diminish the severity of the flaw.
Figure: Mechanism of persistent worker processes reusing dirty memory across HTTP requests. Source: Datadog Security Labs
Upload Progress Disabling Is Ineffective: Configuration Tweaks Cannot Mask Memory Flaws
Following disclosure, community discussions suggested setting session.upload_progress.enabled = 0 as a temporary workaround. This tweak creates a dangerous false sense of security. While it mitigates certain upload vectors for CVE-2026-109619, it does nothing to block CVE-2026-109618’s memory allocation vulnerability. Leaving the core allocation bug unaddressed leaves hosts completely exposed.
PHP maintainers subsequently issued strict configuration guidance for temporary mitigation. For CVE-2026-109618, the official recommendation mandates setting memory_limit = -1 while enforcing strict request body size limits at the reverse proxy layer and applying cgroups resource caps at the container level. Systems administrators are expressly cautioned against using process-level limits such as RLIMIT_AS or RLIMIT_DATA, as these quota mechanisms trigger the exact allocation failures required for exploitation.
For CVE-2026-109619, in addition to turning off upload progress tracking, PHP 8.5 deployments must configure fatal_error_backtraces = 0. All mitigation settings must be loaded before PHP parses inbound requests, requiring a rolling restart across all worker processes. CERT-EU issued Alert 2026-018 advising organizations unable to immediately deploy runtime patches to isolate affected applications from the network. Datadog recommends filtering suspicious payloads at reverse proxies and edge firewalls.
Paying Down 40 Years of Technical Debt: Immediate Runtime Replacement Is the Only Defense
Examining the progression of PHP2Shell reveals that the real casualty was the long-standing paradigm of coordinated vulnerability remediation: vendors patch, advisories publish, and defenders systematically upgrade. The preliminary leak and four-day pre-disclosure exploitation window eliminated the defensive safety buffer entirely. Both attackers and defenders obtained the patch diffs simultaneously, and automated campaigns fired within minutes of release.
IEEE Spectrum summarized the event with striking clarity: AI is forcing the industry to pay down 40 years of accumulated technical debt. PHP2Shell embodies this dilemma—incrementing a counter prior to memory allocation was an architectural habit that stood unquestioned for decades. Even the fix in PHP 8.5.12 patched the error handling around the failure rather than redesigning the sequence itself.
Operations teams auditing infrastructure for signs of intrusion should monitor three primary indicators: an abrupt surge in out-of-memory errors during request initialization, anomalous multipart POST requests containing unusually large or malformed field names, and unexpected child shell processes spawned under the web server user. Any of these signals suggests active attempts to breach the parser.
When response windows evaporate, configuration tuning remains a fragile stopgap. Edge inspection may filter automated scanners, but cannot resolve intrinsic interpreter vulnerabilities from within. Replacing affected runtimes across every production environment remains the only viable defensive posture.
Reference Links:
- Datadog Security Labs Technical Vulnerability Report
- PHP Official Security Advisories and php.announce #509
- Huntress Threat Intelligence Advisory
- AWS Security Blog Telemetry Notes
- Ars Technica Feature Analysis
- CERT-EU Security Advisory 2026-018
- IEEE Spectrum In-Depth Report