php2shell: PHP Patches Two Unauthenticated RCEs with a Single Corrupted-Memory Root Cause
A single unauthenticated HTTP request can produce a shell on any unpatched PHP site, and Talos's estimate that half of public PHP installs are too old to ever receive a fix puts a large share of the web at permanent risk. The operational stakes are just as high: reloading FPM is not enough, and default mod_php configuration is a confirmed attack path.
PHP shipped 8.5.12, 8.4.27, 8.3.36, and 8.2.35 on October 21, 2026 to close two unauthenticated RCE vulnerabilities rated CVSS v4.0 9.2. Researchers named the pair php2shell because a single HTTP request can yield remote code execution before application code runs. CVE-2026-109618 is triggered through multipart uploads when an OOM abort via longjmp leaves half-initialized memory for cleanup routines; CVE-2026-109619 is a use-after-free in worker global state, confirmed via session.upload_progress and, on PHP 8.5, fatal error backtraces. Both share a single root cause: memory left damaged on an abnormal request boundary.
Exposure is broad. Wiz puts PHP behind roughly 70% of websites, Dataminr found at least two million public PHP instances on disclosure day, and Cisco Talos estimates about half of PHP sites run versions old enough that no official update exists. Branches 8.1 and earlier are EOL and get no patch. QiAnXin reported in-the-wild exploitation on October 22; Talos had not confirmed compromise as of October 21.
The upgrade itself is only half the job: verify CLI and FPM versions separately, restart rather than reload workers, confirm process start times, and re-check configuration after upgrading. For installs that cannot move off EOL branches, the recommended mitigation disables session.upload_progress, disables fatal error backtraces on PHP 8.5, and avoids RLIMIT_AS/RLIMIT_DATA as memory_limit substitutes. The disclosure timeline also shows AI-assisted auditing at work: three teams using frontier models converged on the same root cause within weeks.
The PHP Foundation funded an external audit in 2024, core developers noticed OOM signals, and the issue was shelved because nobody had a concrete exploit path. A known bug without a known path is not a closed case; the foundation's own 'structural failure' postmortem treats the delay, not the original discovery, as the mistake.
Wiz's statement that frontier AI turned a long-standing flaw into a usable exploit is the sharpest claim here. Three independent teams converged on the same root cause within weeks of each other using AI-assisted tooling, while Cloudflare and watchTowr observed attackers doing the same kind of work on the offensive side; the same models lowered the cost of both finding and weaponizing this bug.
The two CVEs share a root cause that lives on error paths: longjmp during OOM and stale worker state after an abnormal request. C codebases typically test happy paths far harder than these boundaries, and PHP's case shows that cleanup logic running on half-initialized memory is exactly where critical RCEs hide.
The disclosure gets a sarcastic salute for PHP's continued relevance, while the reality check is that legacy sites and open-source systems keep a huge attack surface alive. One operator reports cutting PHP's default timeout from 30 to 8 seconds and seeing failure rates drop, leaving the ideal production timeout unresolved. The writeup stops short of saying whether php2shell leads to a concrete shell, so the most obvious impact question hangs unanswered.
You only realize how powerful PHP is when a vulnerability like this comes out 👍
Indeed, there are way too many old websites and assorted open-source systems.
We cut PHP's default timeout from 30 seconds to 8 seconds, and the failure rate actually went down. What do you set for production?
They didn't say whether this vulnerability can be exploited to get a shell.