PHP2Shell: After-Action Report on the October 2026 PHP Runtime Compromise
TL;DR: Two critical memory-safety defects in the PHP runtime, CVE-2026-109618 and CVE-2026-109619, produced unauthenticated remote code execution at the interpreter layer. Both carry CVSS v4.0 9.2 ratings. Emergency fixes shipped October 21, 2026, one day ahead of the coordinated schedule, after an accidental demo video leak collapsed the disclosure window. Honeypot telemetry places first observed exploitation attempts at October 17, four days before anyone outside the process knew.
What the attack surface actually looks like
This is not an application-layer bug. Nothing in WordPress core, no plugin, no theme introduced it and nothing in that stack can remediate it. The defect sits in the interpreter that executes the application, which means every PHP application on an affected host inherits the exposure simultaneously. Magento, Laravel, custom in-house code, your staging environment nobody has logged into since March. Same runtime, same problem.
The exposure profile is about as bad as it gets on paper. No authentication. No user interaction. The trigger is an HTTP request to a PHP endpoint, so the attack surface is coextensive with the site’s public reachability.
PHP’s advisories name PHP-FPM, Apache mod_php, php-cgi, FrankenPHP, and LiteSpeed as affected SAPIs. mod_php draws the sharpest warning, because exploitation there can land before application code executes at all. Whatever request filtering, auth middleware, or WAF-adjacent logic lives inside the application never gets a vote.
The FPM caveat worth getting right
There is a real technical distinction between the two advisories that got flattened in early coverage.
| CVE-2026-109618 | CVE-2026-109619 | |
|---|---|---|
| Root cause | Memory corruption during OOM handling of incomplete request data | Stale global references surviving request teardown, leading to use-after-free |
| mod_php | Confirmed exploitation | Confirmed exploitation |
| PHP-FPM | Susceptible, no complete demonstrated exploit for this flaw | Validated session-lifecycle RCE |
| Notable path | Cleanup logic processing unfinished internal structures | Session upload progress, among others |
The takeaway for anyone running FPM: the absence of a published FPM exploit for the OOM flaw is not a mitigating control. The second CVE closes that door anyway. “We’re on FPM, not mod_php” is a defensible statement about relative risk and an indefensible basis for deferring the patch.
The CVSS 9.2 question
Both CVEs scored 9.2 rather than a perfect 10, and the gap is attributable to attack complexity and deployment-dependent conditions. Exploit reliability varies with build configuration, loaded extensions, frontend proxy behavior, and memory layout.
That nuance has been weaponized in both directions. Some shops read 9.2 and heard “not quite critical.” Others read it and ignored the complexity caveat entirely. The accurate reading: working exploitation has been demonstrated, so the complexity factor describes effort required per target, not a meaningful barrier against a motivated actor running broad scans.
Privilege boundary matters here too. Confirmed execution runs under the web worker account. Not root. For most deployments that still means read access to application secrets, database credentials in config files, write access to the webroot, and the ability to spawn processes. Lateral movement from there is a function of how well the host was segmented, which in shared and managed hosting is frequently not at all.
Timeline reconstruction
| Date | Event |
|---|---|
| 2024 | Quarkslab audit follow-up work surfaces early indicators of the OOM defect. No exploit vector established at the time. |
| Aug 11, 2026 | Researcher Calif reports RCE sharing the same root cause. |
| Aug to Sep 2026 | Additional research clarifies impact and identifies further attack paths. Wiz independently discovers and reports both flaws. |
| Oct 17, 2026 | Amazon MadPot honeypot telemetry records first exploitation attempt. Four days pre-disclosure. |
| Oct 20, 2026 | CVE identifiers circulate early. A demonstration video is published accidentally. |
| Oct 21, 2026 | Emergency releases ship, one day ahead of the planned Oct 22 date. |
Two findings deserve attention in any honest post-mortem.
First, the 2024 signal. The PHP Foundation has publicly acknowledged that compatibility tradeoffs, resource constraints, and its own decision process delayed remediation of the OOM issue after early indicators appeared. That is an unusually candid admission from an upstream maintainer and it reflects a structural problem rather than an individual failure. A volunteer-heavy foundation maintaining a runtime that serves a substantial fraction of the web does not have the headcount to chase every ambiguous audit signal to ground.
Second, the October 17 telemetry. Amazon has been appropriately careful here: it observed attempts and it is unclear whether those early attempts would have succeeded against production systems. Pre-disclosure activity does not automatically imply a leak or an independent discovery by a hostile party. It does mean the window where defenders had zero awareness and attackers had some was at minimum four days wide.
Where defenses held and where they did not
Cloudflare pushed WAF protections to all plan tiers including Free, and has reported attackers actively modifying payloads to probe around those rules. That is the expected pattern and it tells you what signature-based mitigation is worth here: time, not immunity. Cloudflare’s own guidance still points to patching.
CERT-EU’s recommendation for environments that cannot patch is isolation of internet-facing applications until remediation is applied and verified. That is the correct posture when the vulnerable component is the execution engine itself.
The temporary measures in PHP’s technical advisories, including memory-handling adjustments and disabling session upload progress, reduce specific paths rather than closing the defects. memory_limit=-1 in particular is incomplete and carries its own resource-exhaustion implications. These belong in a change-freeze bridge, not a hardening guide.
Remediation and version verification
Minimum fixed upstream releases:
| Branch | Affected | First fixed |
|---|---|---|
| 8.5 | 8.5.0 to 8.5.11 | 8.5.12 |
| 8.4 | 8.4.0 to 8.4.26 | 8.4.27 |
| 8.3 | 8.3.0 to 8.3.35 | 8.3.36 |
| 8.2 | 8.2.0 to 8.2.34 | 8.2.35 |
Version triage is where this incident is generating the most operational error, for two reasons that cut in opposite directions.
PHP 8.1 and older are unsupported upstream. PHP supplied minimal source backports for 7.4, 8.0, and 8.1 for this incident specifically, which does not restore support for those branches. Meanwhile, distribution packages carry backported fixes under base version numbers that look stale. Ubuntu’s fixed packages include 8.1.2-1ubuntu2.28 for 22.04 and 8.3.6-0ubuntu0.24.04.13 for 24.04. Reading the base version alone produces a false positive on 8.1.2 and a false negative on 8.3.6. Read the full package revision and the vendor advisory.
Deployment sequence:
- Inventory every PHP runtime in scope. Production, staging, subdomains, non-WordPress PHP applications, anything with a resolving hostname.
- Confirm a fixed upstream release or a documented vendor backport covering both CVEs.
- Apply and restart the affected services or workers. Ubuntu explicitly notes that package installation alone can leave applications needing a restart. An FPM pool running pre-patch code after a successful
apt upgradeis still vulnerable and will still report the new version from the CLI. - Verify the running environment, not the installed package. Check what the web SAPI reports.
- Investigate historical activity for any installation that was internet-reachable.
Amazon’s guidance sets the investigation floor at October 17: anomalous requests, unexpected process execution under the web user, and filesystem changes in the webroot. Patching stops forward exploitation of the fixed defects. It establishes nothing about the preceding period.
For managed hosting, the question that cannot be answered with marketing language: has the PHP runtime serving this domain received fixes for both CVE-2026-109618 and CVE-2026-109619, and have the affected workers been restarted?
Claims that did not survive scrutiny
- “All PHP 8 is safe.” The branch number alone establishes nothing. 8.0 and 8.1 are unsupported; supported branches shipped vulnerable releases through October 21.
- “Old version number equals unpatched.” Vendor backports break naive version comparison in both directions.
- “Both CVEs are 10.0.” Vendor rating is 9.2 under CVSS v4.0 for each.
- “PHP2Shell gives root.” Confirmed execution is under the web worker’s privileges.
- “A WordPress update fixes it.” Different layer entirely.
- “Cloudflare handles it.” Cloudflare says otherwise.
- “70% of sites were breached.” PHP market-share figures are not compromise counts. Exposure, attempted exploitation, and confirmed compromise are three separate populations and only the first is large.
- “It’s a mandatory two-CVE chain.” Two distinct defects under one marketing name.
What this incident should change
The AI-assisted research angle will get the headlines. OpenAI has stated that Calif used GPT-5.6 Sol during the research, and Wiz independently found and reported both flaws. That is a meaningful data point about tooling accelerating vulnerability discovery in mature, heavily-audited C codebases, and it cuts both ways on timeline compression.
The less glamorous finding is the one worth acting on. A 2024 audit signal sat unresolved for roughly two years in a runtime with enormous blast radius, because the maintaining organization lacked the resources to chase it and the fix carried compatibility cost. Nothing about AI-assisted discovery fixes that. If anything, faster discovery against a slow remediation pipeline widens the gap between when a flaw becomes findable and when it becomes fixed.
For operators, the structural lesson is runtime inventory. Most organizations that struggled this week struggled because they could not quickly answer which PHP versions were running where, across how many hosts, under which SAPIs. That question should be answerable in minutes, not days, and the next runtime-layer CVE will ask it again.
Key Takeaways
- Two distinct memory-safety defects in the PHP interpreter, both CVSS v4.0 9.2, both unauthenticated and requiring no user interaction
- The vulnerable component is the runtime, not the application. No WordPress, plugin, or theme update remediates it
- mod_php is highest risk because exploitation can precede application code execution; PHP-FPM is confirmed exploitable via the stale-state CVE regardless
- Minimum fixed upstream releases are 8.2.35, 8.3.36, 8.4.27, 8.5.12; distribution backports make base version numbers unreliable as a triage signal in both directions
- Worker restart is a required remediation step, not an optimization
- Exploitation attempts predate public disclosure by four days; investigation scope should start at October 17 for any exposed host
- Execution lands under the web worker account, not root, which bounds the impact without making it acceptable
- The root organizational failure was a two-year gap between an audit signal and a fix, driven by maintainer resource constraints rather than technical difficulty