PHP2Shell: Inside CVE-2026-109618 and CVE-2026-109619
Somewhere around 7:43 AM UTC on October 21, 2026, Cloudflare's edge network started logging a pattern of malformed multipart uploads hitting PHP endpoints across thousands of unrelated customer sites. PHP's upload-progress handler was returning freed worker memory to the client inside a PHPSESSID response cookie — which meant, in plain terms, that attackers were pulling raw fragments of server memory out of a cookie before anyone had even logged in. Six hours later, the PHP project pushed four emergency releases at once. By the following week, Palo Alto Networks' Cortex Xpanse had counted over 22.6 million exposed instances potentially vulnerable to the two flaws now being called PHP2Shell.
If you run PHP-FPM, mod_php, or anything built on Magento, Shopware, WooCommerce, Laravel, or a dozen other frameworks, this isn't background noise. It's a patch-today situation. Here's what actually happened, why the usual config-tweak playbook doesn't cut it this time, and what Jalsonic Networks recommends for teams trying to close the gap before attackers close it for them.
What Actually Breaks When PHP Runs Out of Memory
CVE-2026-109618 lives in a part of PHP most developers never think about: what happens the instant a request blows past memory_limit. A fatal error during a request, typically triggered when a request crosses the memory limit, interrupts native PHP code before it has a chance to clean up. That interruption is handled through a low-level control-flow mechanism called longjmp(), and handling out-of-memory errors through longjmp() leaves request memory uninitialized because control flow isn't properly managed on the way out.
In isolation, uninitialized memory is a code smell. Paired with PHP's session upload-progress feature — the thing that powers those "upload is 43% complete" progress bars — it becomes something much worse. Security researchers tracking the issue classify it as an upload-progress unserializer use-after-free, and the vulnerable code path traces back to PHP 5.4.0, released in 2012. That's fourteen years of production PHP carrying this exposure, unnoticed, in both Apache's mod_php and PHP-FPM.
What makes CVE-2026-109618 genuinely dangerous isn't just that it enables remote code execution — it's that the memory disclosure happens on its own, as a side effect of normal-looking traffic. An attacker doesn't need a login, an API key, or a vulnerable plugin. They need a crafted multipart request and a server configured the way most PHP servers are configured by default.
The Second Door: Stale State and CVE-2026-109619
Where CVE-2026-109618 is about what gets left behind when memory runs out, CVE-2026-109619 is about what gets reused afterward. PHP-FPM workers don't die after every request — they stay alive and handle the next one, which is normally a performance win. The problem is that longjmp() fatal error handling leaves global memory pointing to freed regions, and if the same worker processes a later request, PHP may access that stale state before normal initialization has a chance to reset it.
Researchers have documented two separate exploitation paths feeding into this single root cause: a fatal-error backtrace use-after-free affecting PHP's newer diagnostic backtrace feature, and a related type-confusion condition inside OPcache, the bytecode caching engine nearly every production PHP install runs for performance. One independent research team that reproduced the exploit chain put it bluntly: application-level authentication can't block an attack, because PHP processes the malicious request before any application code runs. Your WAF rules, your login wall, your rate limiter — none of it matters, because the vulnerability fires in the engine itself, before your app ever sees the request.
Both vulnerabilities share a CVSS v4.0 score of 9.2, and both were independently discovered and reported to PHP's security team roughly two months before public disclosure, through coordinated channels, before a leak forced PHP's hand. Details leaked on October 20, and watchTowr confirmed working remote code execution the same day — about eighteen hours before PHP's official patch shipped.
Why Configuration Changes Won't Save You
Here's where a lot of ops teams are going to make an expensive mistake this week. Several vendors have published stopgap php.ini settings — disabling session.upload_progress, removing the memory limit entirely, turning off fatal-error backtraces — as a way to blunt the two attack paths while you schedule a maintenance window. Those settings are a quick fix for every build strategy, and they're worth applying immediately if you can't patch this hour. But they are not a fix. They reduce the attack surface of the specific demonstrated exploit paths; they do nothing for the underlying memory-safety defect itself.
PHP's own security team has been explicit about this. There are no complete mitigations — updating is the only safe choice. The patched releases rewrite how memory exhaustion interrupts execution in the first place: rather than tearing through cleanup mid-operation, a soft limit now defers the error until PHP reaches a safe point, letting an in-progress operation finish initializing its data before the fatal path runs. That's a structural change to the interpreter's control flow, not a toggle you can flip in php.ini.
The fixed versions are PHP 8.5.12, 8.4.27, 8.3.36, and 8.2.35, all released October 21, 2026. Every PHP version from 5.4 through 8.5.11 is vulnerable, but the PHP project is not releasing fixes for PHP 8.1 or earlier, since those branches have already reached end of life. If you're still running 7.x or 8.0/8.1 in production, the only sanctioned paths forward are a distribution-maintained backport, a vendor-patched build, or — the option we'd push hard for — finally retiring that branch. A fourteen-year-old memory-safety bug in EOL software is not a one-off; it's a preview of the next one.
For teams managing dozens or hundreds of PHP instances across containers, bare-metal hosts, and managed hosting accounts, the practical challenge isn't understanding the fix — it's finding every place PHP is running, confirming the exact minor version, and sequencing the rollout without breaking dependent services. That inventory-and-rollout problem is exactly where Jalsonic Networks' patch management engagements focus, because the technical fix is published; the operational risk is everything that happens between "we should patch" and "we actually did."
Key Takeaway: CVE-2026-109618 and CVE-2026-109619 are unauthenticated, pre-authentication RCE flaws in PHP's core memory-handling code, not in any application, plugin, or framework running on top of it. Config changes like disabling session upload progress or raising the memory limit reduce exposure to known exploit paths but leave the underlying defect intact. The only complete fix is upgrading to PHP 8.2.35, 8.3.36, 8.4.27, or 8.5.12.
Not sure which of your servers are still exposed? Jalsonic Networks runs emergency PHP version audits and managed patch rollouts for teams who can't afford to guess. Book a consultation with our team and we'll map your exposure and get you to a patched build without a scramble.
FAQ
Conclusion
PHP2Shell is the kind of vulnerability that makes a fourteen-year-old code path suddenly feel urgent. The combination — unauthenticated, pre-application, engine-level, and already being exploited in the wild before the patch even shipped — puts it in rare company. Partial mitigations buy you hours, not safety. The actual fix is a version number: 8.2.35, 8.3.36, 8.4.27, or 8.5.12, depending on your branch. Everything else is a stalling tactic while you get there. If your infrastructure spans more servers than you can patch in an afternoon, that's exactly the kind of work Jalsonic Networks handles daily — get in touch and we'll help you close the window fast.