PHP2Shell: AI Turned a Decade-Old PHP Engine Bug Into Pre-Auth RCE — Emergency Patches for CVE-2026-109618 and CVE-2026-109619 Cover Every Version Back to PHP 5.4

PHP2Shell: AI Turned a Decade-Old PHP Engine Bug Into Pre-Auth RCE — Emergency Patches for CVE-2026-109618 and CVE-2026-109619 Cover Every Version Back to PHP 5.4

PHP2Shell: AI Turned a Decade-Old PHP Engine Bug Into Pre-Auth RCE — Emergency Patches for CVE-2026-109618 and CVE-2026-109619 Cover Every Version Back to PHP 5.4

PHP shipped emergency releases on October 21 that fix two critical vulnerabilities in the language runtime itself, letting unauthenticated attackers run code on the web server behind it. The flaws — CVE-2026-109618 and CVE-2026-109619, both rated CVSS v4.0 9.2 and nicknamed PHP2Shell — are patched in PHP 8.5.12, 8.4.27, 8.3.36, and 8.2.35. Because they sit in the engine rather than in any site's code, even a "Hello World" page on a vulnerable version is exposed, and nearly every PHP release back to PHP 5.4 is affected by at least one of them.

Wiz Research, working with the research firm Calif and OpenAI's Codex Security team, traces all four underlying bugs to a single design problem: how PHP handles fatal errors during request processing, particularly out-of-memory failures. A request that dies mid-flight can leave corrupted internal state behind, and a later request handled by the same worker reuses that stale state. Under CVE-2026-109618, an upload-progress unserializer use-after-free lets an attacker URL-encode live worker memory — passwords, tokens, API keys, certificates belonging to other requests — into a PHPSESSID response cookie, even when the application never calls session_start(). CVE-2026-109619 groups a fatal-error backtrace use-after-free and an OPcache type confusion that corrupt process memory into code execution. Wiz demonstrated pre-authentication RCE against WordPress, Drupal, and Joomla; PHP's advisory singles out mod_php as the highest risk, because a single unauthenticated request can trigger before any application code runs.

The release was pulled forward by a leak. Wiz found the first flaw on August 19 using AI tooling (Wiz Atlas, Gemini 4 Argon, GPT-5.6 Sol), confirmed working exploits against Drupal and WordPress within two days, and reported to PHP on August 24; PHP acknowledged on September 21 and coordinated a disclosure for October 22. On October 20 a Hacker News post named both CVE IDs, Calif mistakenly published a proof-of-concept video, and Chainguard shipped patched container images six hours before the patch itself — so PHP moved the release to 14:00 UTC on October 21. The PHP Foundation added that a 2024 external audit had spotted the first signs of the out-of-memory flaw, but with no working exploit route the fix stalled — a delay it called "a structural failure" of its decision process.

Exploitation followed fast. Cloudflare switched on emergency firewall rules by default at 03:02 UTC, before the patch existed, and watched attackers adapt payloads around them; watchTowr reported "active exploitation attempts" of both CVEs by 14:19 UTC on release day; Amazon's MadPot honeypot network saw attempts four days before the patches. No confirmed break-in of a named server has been reported, and neither CVE was in CISA's KEV catalog as of October 22 — but precautionary outages hit anyway: BambooHR took its platform offline across the US, Canada, and Ireland, and Dutch government services including MijnOverheid, DigiD, and the lower house of parliament went dark, with the Dutch cyber center saying it had not seen abuse yet but urging everyone to patch. Wiz frames PHP2Shell as an AI inflection point: turning a decade-old flaw into a working exploit took one researcher about a week, where it would previously have taken a world-class team months.

What Should You Do?

  1. Update the PHP runtime itself — 8.5.12, 8.4.27, 8.3.36, or 8.2.35 — then restart PHP-FPM, Apache, and any long-running workers. Updating WordPress or Laravel does not update PHP; the runtime comes from your server package, host, or container image.
  2. If you cannot update immediately, apply the partial mitigations as stopgaps — for CVE-2026-109618 set memory_limit=-1, keep post_max_size low, and enforce request-size limits at the proxy; for CVE-2026-109619 set session.upload_progress.enabled=0 (and fatal_error_backtraces=0 on PHP 8.5) and restart every worker. PHP is explicit that only updating is a complete fix.
  3. Hunt for compromise signals — unusual multipart requests followed by memory-limit errors or repeated HTTP 500 responses, oddly large or malformed PHPSESSID response cookies, and unexplained PHP worker restarts.
  4. Plan the EOL branches — PHP 8.1 and older receive no official updates and 8.2 reaches end of life on December 31, 2026; source backports exist for 7.4, 8.0, and 8.1, and distribution packages can carry the fix under an old-looking version, so check the package changelog for the CVE rather than the version string.

The WAF Angle

This is the second story in a week where application code is irrelevant — the runtime itself is the attack surface, exactly like the Next.js optimizer RCEs we covered on October 14. WAFs earned their keep here as stopgaps: Cloudflare shipped emergency request-shape rules before any patch existed, and the memory-disclosure path — an oversized PHPSESSID cookie — is precisely the kind of response anomaly a WAF can flag. The durable lesson is to treat the language runtime like a dependency you patch on a schedule, because engine-level flaws sit underneath the WordPress plugin flaws like Bricksforge we covered in the same ecosystem — patching the app while the engine stays vulnerable fixes nothing.

Sources