Published
- 7 min read
By Allan D - Editor, AI Security Wire
PHP2Shell: Two Critical PHP RCE Flaws (CVE-2026-109618, CVE-2026-109619)
Two critical flaws in the PHP engine, disclosed on October 21, 2026, let an unauthenticated remote attacker execute code as the web worker account. CVE-2026-109618 and CVE-2026-109619 both carry a CVSS v4 score of 9.2 from the PHP security team. Wiz Research, which found them with Calif and OpenAI and calls the combined work “PHP2Shell”, says it built working exploits against WordPress, Drupal and Joomla container images. The fix is in PHP 8.5.12, 8.4.27, 8.3.36 and 8.2.35.
What was disclosed
| Field | CVE-2026-109618 | CVE-2026-109619 |
|---|---|---|
| PHP advisory title | RCE via OOM corruption (GHSA-w8hw-w9fx-j79w) | RCE via stale global state (GHSA-6wmf-4rv5-p3rp) |
| CVSS v4.0 (PHP security team, secondary) | 9.2 Critical, AV:N/AC:H/AT:P/PR:N/UI:N | 9.2 Critical, same vector |
| CVSS v3.1 (NVD, primary) | 9.8 Critical, AV:N/AC:L/PR:N/UI:N | 9.8 Critical, same vector |
| CWE | 416, 755, 824, 1325 (advisory also lists 1419) | Same |
| Affected | PHP before 8.2.35, 8.3.36, 8.4.27, 8.5.12 | Same |
| Published | October 21, 2026 | October 21, 2026 |
The two scores use different scales. NVD’s v3.1 rating of 9.8 assumes low attack complexity, while the PHP team’s v4.0 vector rates complexity high and adds an attack requirement. In our reading, that difference is the main reason the numbers diverge.
How the bugs work
Both flaws are memory-safety problems in how PHP handles failures part-way through a request. They are not bugs in any one application, so a stock install can be exposed.
CVE-2026-109618 (out-of-memory corruption). PHP uses longjmp() to abandon a request when it runs out of memory. According to the advisory, if that happens while request memory is only partly initialized, shutdown can later read or branch on invalid state. The allocation that fails does not have to relate to the damaged memory. The advisory says multipart parsing can push a request into an out-of-memory condition while staying inside apparent limits, because of a missing usable content length, unlimited headers per part and empty file controls that bypass max_file_uploads.
CVE-2026-109619 (stale global state). PHP worker processes keep global state, including error, session, object and extension state, that can point at memory owned by a previous request. If that memory is freed and the stale pointer is used before normal request initialization, the result is a use-after-free. The advisory names two early consumers: INI diagnostics raised before request initialization, and session upload-progress handling. The strongest demonstrated case is the PHP 8.5 fatal_error_backtraces path. The PHP advisories tie the fatal-backtrace and session upload-progress paths to this CVE. An attacker needs one request to leave the stale state and a second to consume it on the same worker.
Wiz describes four bugs across the two CVEs: a use-after-free in upload-progress unserialization, a remote memory disclosure through a stale session ID pointer encoded into a PHPSESSID cookie, a use-after-free in the fatal-error backtrace, and an OPcache type confusion. Wiz’s mapping of each bug to a CVE is not clear in the published table, so we do not attribute individual bugs to individual CVE IDs.
Who is exposed
What each source demonstrated differs, and the differences matter for triage:
- Apache mod_php: the PHP advisory says unauthenticated RCE over HTTP was validated with default PHP input and memory limits, in prefork configurations, for CVE-2026-109618. The fatal-backtrace and session paths of CVE-2026-109619 were also confirmed here.
- PHP-FPM: no complete exploit for CVE-2026-109618, though source analysis suggests susceptibility. The session-lifecycle path of CVE-2026-109619 was validated, and the advisory says it depends on a suitable application operation.
- FrankenPHP and LSAPI: for CVE-2026-109618 the advisory calls FrankenPHP likely susceptible based on source analysis, and LSAPI likely open to application-specific exploits, unvalidated. For CVE-2026-109619 it calls LSAPI a conditional candidate and says an equivalent early configuration consumer was not established in FrankenPHP’s default configuration, which is not the same as immune. PHP.net’s announcement says the risk covers all PHP installations serving web requests, including PHP-FPM, Apache with mod_php, php-cgi, FrankenPHP and LiteSpeed, and is highest for mod_php.
Wiz says that “every PHP version released in the last decade is affected by at least one of these vulnerabilities”, going back to 5.4, and that it reached unauthenticated RCE against the latest WordPress, Drupal and Joomla container images at the time of testing. The PHP advisories list only the 8.2 to 8.5 branches, and NVD’s CPE ranges have no lower bound on the 8.2 entry, so they match every version before 8.2.35. PHP.net says PHP 8.1 and older no longer receive official updates. It says the PHP security team provided minimal source backports for PHP 7.4, 8.0 and 8.1, and that some distributions and LTS vendors ship backported fixes. If you run an older branch, do not assume it is safe: check the backports or your distribution or LTS vendor.
Reliability is not guaranteed. The advisory says success depends on the build, extensions, frontend behavior and allocator layout, and that more workers lower the success rate without removing the condition.
The AI-assisted discovery angle
Wiz says its researchers found the bugs using Wiz Atlas, Gemini 4 Argon and GPT-5.6 Sol, and that “a single researcher completed in a week what previously would have taken a world-class team months of work”. By Wiz’s timeline, discovery began on August 19, Drupal and WordPress RCE were confirmed on August 20 and 21, the PHP security team was told on August 24, and a coordinated fix began on September 21. These are Wiz’s own claims and we have not independently verified the role of the AI models. For defenders, the practical point is the compressed timeline: Wiz says it could “develop and adapt working exploits across multiple applications in hours”.
Exploitation status
As of October 22, 2026, we found no report of attacks in the wild in the PHP advisories, php.net, oss-security or Wiz. The CISA coordinator SSVC entry in NVD, stamped 14:34 UTC on October 21, lists exploitation as “none” and automatable as “no”, with technical impact “total”. Neither CVE was in the CISA KEV feed as of its October 21 14:04 UTC release, which predates the CVE publication, so KEV status needs rechecking. Wiz describes a combined exploit script called php2shell but does not say whether it is public, and we found no public proof-of-concept in the sources we reviewed. That can change quickly after disclosure of this kind.
What to do now
- Upgrade to PHP 8.5.12, 8.4.27, 8.3.36 or 8.2.35 (or later on the same branch). Restart all workers, because the bugs live in long-running worker state. Rebuild container images rather than patching running containers.
- If you cannot upgrade immediately: on PHP 8.5 set
fatal_error_backtraces=0; setsession.upload_progress.enabled=0(the advisory suggests this even after patching if you do not need it); keeppost_max_sizeconservative and enforce decoded request size at the frontend; block multipart requests at the edge if the application does not use them. For CVE-2026-109618 the advisory also lists setting and enforcingmemory_limit=-1administratively, with the caveat that anmmap()failure can still triggerlongjmp(). The advisories say none of these is complete. - Avoid
RLIMIT_ASandRLIMIT_DATAas memory limits, since the advisory says they trigger the vulnerablelongjmp()path. It suggests a cgroupmemory.maxwith caveats, andpm.max_requests=1as a risk reducer. - Check your CDN or WAF vendor. Wiz says Akamai, AWS, Cloudflare, Fastly, Google, Imperva, Microsoft and Vercel, among others, helped prepare mitigations. Confirm what your provider has actually deployed rather than assuming coverage.
- Hunt for indicators, as suggested by Wiz: unusual multipart requests followed by memory-limit errors or repeated HTTP 500 responses, unusually large or malformed
PHPSESSIDcookies and unexplained PHP worker churn. The PHP advisory notes that logs alone do not prove a system is safe.
Why it matters
Wiz says PHP powers about 70% of websites. These flaws sit below the application layer, so a hardened application on a vulnerable runtime is still exposed. Any AI-adjacent dashboard, admin panel or self-hosted frontend that runs on PHP needs the same patch-and-restart treatment as the rest of the estate.
References
- PHP security advisory GHSA-w8hw-w9fx-j79w, RCE via OOM corruption (CVE-2026-109618)
- PHP security advisory GHSA-6wmf-4rv5-p3rp, RCE via stale global state (CVE-2026-109619)
- NVD: CVE-2026-109618
- NVD: CVE-2026-109619
- Wiz Research: PHP2Shell
- oss-security: CVE-2026-109618 announcement, 21 October 2026
- PHP.net release announcements, 21 October 2026
Frequently Asked Questions
- Which PHP versions fix CVE-2026-109618 and CVE-2026-109619?
- PHP 8.5.12, 8.4.27, 8.3.36 and 8.2.35, released on October 21, 2026. Both GitHub advisories list the affected ranges as earlier than those releases on each branch. The PHP project says updating is the only complete mitigation.
- Are these flaws being exploited in the wild?
- No source we reviewed reports in-the-wild exploitation as of October 22, 2026. The CISA coordinator SSVC entry in NVD lists exploitation as none, and neither CVE was in the CISA Known Exploited Vulnerabilities feed as of its October 21, 14:04 UTC release. Wiz and the PHP advisories do describe working exploits built by the researchers against WordPress, Drupal and Joomla containers and, in the PHP advisories, against Apache mod_php.
- Is PHP-FPM affected?
- Partly. For CVE-2026-109618 the PHP advisory says no complete PHP-FPM exploit has been demonstrated, though source analysis suggests susceptibility. For CVE-2026-109619 the advisory says a session-lifecycle path was validated against both mod_php and PHP-FPM. Treat FPM as in scope for patching.
- Can I mitigate without upgrading?
- Only partly. The advisories offer workarounds such as session.upload_progress.enabled=0, fatal_error_backtraces=0 on PHP 8.5, conservative post_max_size, memory_limit=-1 enforced administratively for CVE-2026-109618, and blocking unneeded multipart requests at the frontend. They state that none is complete and that upgrading is the only reliable fix.