The PHP Foundation released an emergency out-of-band update today, fixing two critical remote code execution flaws, CVE-2026-109618 and CVE-2026-109619, each scored 9.2, that let unauthenticated attackers run code in PHP's native request-parsing layer before any application logic runs. The embargo broke down fast: details leaked to Hacker News ahead of schedule, Cloudflare had already spotted live attacks, and Sansec expects mass exploitation within roughly 15 minutes. PHP's patched versions are 8.5.12, 8.4.27, 8.3.36, and 8.2.35, and the foundation stresses there are no real mitigations, only an update makes you safe, with Apache mod_php being the easiest to weaponize. Analysts note that reliable public exploits remain unproven so far, but the guidance is clear: patch internet-facing PHP first and check logs for signs of compromise.
Two critical PHP RCE flaws force an emergency patch, and the embargo leaked anyway
Two critical remote code execution bugs in PHP's core sent the PHP Foundation scrambling for an out-of-band release today. The details had already hit social media the day before, and Cloudflare says attackers were watching.
The PHP Foundation has now confirmed two critical vulnerabilities in the language core, and it isn't mincing words. They're tracked as CVE-2026-109618 and CVE-2026-109619, and both carry a CVSS v4.0 score of 9.2. Each lets an unauthenticated attacker run arbitrary code on a server running PHP.
The advisory reads "Critical remote code execution vulnerabilities, update now," which is about as blunt as a security notice gets. PHP is telling everyone to patch immediately.
The detail that matters most is where the bugs live. Both sit in PHP's native request-parsing code, the C layer that runs before any of your application code ever executes. Patch that from inside a WordPress plugin and you'll have done nothing. It's a server-level PHP update, and as Sansec put it, "a store cannot apply [it] from its own code."
That boundary is also why the community has taken to calling these PHP2Shell. The name references dropping into a remote shell on a compromised host, and it borrows from an older "X2Shell" pattern that usually describes OS-level flaws. This time the target is the language core itself.
PHP still powers a huge share of the web. A flaw in a single CMS is a nuisance. A flaw in the runtime underneath them all is a genuinely different problem.
The leak before the embargo
This one is worth attention for the way it unfolded, more than anything else.
On the morning of October 20, a post hit Hacker News claiming two critical PHP RCEs rated 10.0, affecting everything from PHP 5 up. It named both CVEs. The post went down hours later, but the blast radius was already drawn. watchTowr CEO Benjamin Harris told BleepingComputer the leaked flaws were "indeed real," and said it believed it had reproduced CVE-2026-109618 while declining to share technical details before the patches shipped.
That 10.0 figure never stuck. PHP's own advisory settled on 9.2, driven by the high attack complexity and the requirement for specific conditions, per BleepingComputer.
PHP's team had actually hedged for exactly this scenario. Its advance notice reserved the right to release early "should details of either vulnerability become public, or should evidence of active exploitation appear in the wild." The window it carved out collapsed faster than expected.
Cloudflare was already observing attacks by disclosure time. CTO Dane Knecht confirmed early attacks and pushed an initial set of blocking rules to all customers, though he stressed these were temporary measures. Sansec, for what it's worth, expects mass exploitation to begin within roughly 15 minutes of the release.
The lesson is an uncomfortable one for the coordinated-discipline model: once details hit social media, the gap between public knowledge and a vendor patch can collapse within hours. That gap here closed in under a day.
The mechanics, and a reliability caveat
The first bug, CVE-2026-109618, is an out-of-memory corruption path. PHP uses longjmp() to bail out on memory errors, exiting the current context. In some cases request memory is only partially initialized yet still reachable, and PHP can fail to account for that early exit. A later branch on the resulting garbage can turn into RCE.
Several multipart-parsing tricks push PHP into that state. A request without a usable Content-Length can slip past the initial post_max_size check and keep feeding decoded body data. A single part can carry an unrestricted number of headers, consuming far more memory inside PHP than it occupies on the wire. Empty file controls don't count toward max_file_uploads but still build metadata arrays.
Apache mod_php is the highest-risk target because it calls the request shutdown procedure unconditionally, even when startup has failed. An attacker can force that OOM entirely before any application code runs. PHP validated a complete exploit over HTTP against mod_php with default input and memory limits and normal prefork setups. PHP-FPM and FrankenPHP are also at risk, though no complete FPM exploit has been demonstrated for that path yet. LiteSpeed is considered likely but unvalidated.
The fix replaces longjmp() with a delayed, graceful soft OOM at the next VM-safe point, plus an immediate hard OOM via _exit() past a second threshold. The shutdown routine stops processing invalid state.
CVE-2026-109619 is the nastier of the two in my read. It's a use-after-free driven by stale global state. PHP keeps error, session, object, and extension state owned by one request but referenced by the worker, and some operations read that state before the next request resets it.
The advisory frames it as a producer-consumer setup. A producer publishes request-owned state. A consumer reads or acts on it before initialization wipes it. The two can happen in different HTTP requests handled by the same worker.
Two concrete consumer paths were nailed down. One is INI diagnostics raised before request initialization — a warning about an invalid or deprecated setting. The other is session upload progress, on by default and needing no session_start() call. Neither is blocked by hiding diagnostics with error_reporting, the @ suppressor, or disabling display_errors.
The strongest demonstrated case is a PHP 8.5 fatal-error backtrace path: with fatal_error_backtraces enabled, the fatal reporting stores request-owned backtrace state that shutdown always fails to reset. It's the basis of the confirmed mod_php exploitation.
Both CVEs cross-reference each other, since the OOM path can itself produce the stale state behind the second bug. They're really two facets of one class of defect: PHP's handling of mid-request failures leaves behind memory or state a later request can misuse.
Here's the caveat worth holding onto. Analyst Ahmed Sultan, known as 0x4148, built a PHP 8.4.4 lab and tested the chain across PHP-FPM and LiteSpeed. He confirmed the session.upload_progress path was reachable and observable, but reported he could not reproduce a crash or command execution. He argued the published heap-forging chain left an open question about whether session reinitialization actually frees the specific allocation the cached pointers reference.
His conclusion was measured: "An absence of public evidence is not proof an exploit never worked." So the vulnerabilities are real and confirmed by PHP. Whether any given public PoC actually works is still being scrutinized, and Sultan warned against treating either a very confident label or its absence as conclusive.
The only real fix is updating, and PHP is emphatic there are no complete mitigations. The configuration tweaks below narrow the attack surface. They don't make you safe. The fixed versions map cleanly: PHP 8.5 goes to 8.5.12, 8.4 to 8.4.27, 8.3 to 8.3.36, and 8.2 to 8.2.35.
All four actively maintained branches are affected and fixed. Timing that will bite some people: PHP 8.2 reaches end of life on December 31, 2026, and that's its last security fix. If you're on 8.2, this is your nudge to upgrade.
How far back does it actually go? Pre-advisory reporting from CERT-EU and Sansec pointed at everything from PHP 5.4 onward. PHP's official matrix only names those four branches, but anyone still on 7.x, 8.0, or 8.1 should treat themselves as potentially exposed. PHP did drop minimal source backports for 7.4, 8.0, and 8.1 on GitHub, in branches named PHP-7.4-CVE-2026-109618-109619, for people building from source or stuck without LTS vendor access.
Distributions already moved. Debian issued DSA-6574-1, fixing php8.4 at 8.4.27-1~deb13u1 for the stable trixie release. Gentoo put out GLSA 202610-02. PHP says distros and LTS vendors got the patches early, so check your vendor before building from source.
One practical annoyance: if you rely on the volunteer-maintained rpms.remirepo.net, PHP suggests switching to distribution packages or building yourself, since that repo won't have updates on disclosure day.
For teams who genuinely can't patch yet, the middle-ground moves are real but incomplete. For the OOM bug, set memory_limit=-1 enforced where apps can't override it, and lower post_max_size. For the stale-state bug, disable session.upload_progress and, on PHP 8.5, set fatal_error_backtraces=0. None is a substitute for updating, and PHP stresses that no error in your logs proves safety either. CERT-EU's fallback advice for those who can't do anything else is to isolate internet-facing applications from public networks until a fix lands.
Detection is behavioral, since no IoCs have been published. Huntress flags PHP workers starting shells like sh, bash, or cmd.exe, or invoking python, perl, curl, wget, nc, or certutil.exe. Watch for command strings containing /dev/tcp/, fsockopen, or mkfifo, and recon like whoami, id, or uname -a run by the web server. Successful RCE often ends in a web shell for persistence, which maps to MITRE ATT&CK T1505.003.
Here's a practical tip. Running php -v through the CLI can lie about what your web SAPI actually loads. Run a small PHP script through the real web layer and delete it after, and you'll see the effective version, the SAPI, the loaded php.ini, and the relevant settings at once.
Release PHP 8.5.12 · php/php-src
The PHP development team announces the immediate availability of PHP 8.5.12. This is a security release fixing two critical vulnerabilities (CVE-2026-109618, CVE-2026-109619) that can allow unauthe...
Release PHP 8.4.27 · php/php-src
The PHP development team announces the immediate availability of PHP 8.4.27. This is a security release fixing two critical vulnerabilities (CVE-2026-109618, CVE-2026-109619) that can allow unauthe...
Release PHP 8.3.36 · php/php-src
The PHP development team announces the immediate availability of PHP 8.3.36. This is a security release fixing two critical vulnerabilities (CVE-2026-109618, CVE-2026-109619) that can allow unauthe...
Release PHP 8.2.35 · php/php-src
The PHP development team announces the immediate availability of PHP 8.2.35. This is a security release fixing two critical vulnerabilities (CVE-2026-109618, CVE-2026-109619) that can allow unauthe...




