What happened

On October 21, 2026, the PHP project released PHP 8.5.12, 8.4.27, 8.3.36 and 8.2.35, saying they "fix two critical vulnerabilities that can allow unauthenticated remote code execution." Both are memory-safety bugs (CWE-416) in how PHP cleans up after a request fails partway through:

  • CVE-2026-109618, "RCE via OOM corruption": when PHP runs out of memory, it can abort a request while internal data is only partly initialized, and the cleanup step then treats that data as valid.
  • CVE-2026-109619, "RCE via stale global state": internal state from one request can survive after its memory is freed, and a later request handled by the same worker can use it.

PHP scores both CVSS v4.0 9.2, and NVD scores them CVSS 3.1 9.8. The advisory says every PHP installation serving web requests is at risk, including PHP-FPM, Apache with mod_php, php-cgi, FrankenPHP and LiteSpeed. Risk is highest for mod_php, "with a demonstrated exploit where an unauthenticated request can trigger the attack before any application code runs." According to PHP's GitHub advisories, full code execution was validated against mod_php with default limits, and the session path in CVE-2026-109619 was validated against both mod_php and PHP-FPM. Session upload progress is enabled by default, and the application does not need to call session_start().

Wiz Research, Calif and OpenAI found and reported the bugs. Wiz, which named them PHP2Shell, says AI models helped find them and build the exploit. It says every PHP version from the last decade, back to 5.4, is affected, and it demonstrated exploit chains against WordPress, Drupal and Joomla. Disclosure was planned for October 22, but details leaked early: The Hacker News reports that Calif mistakenly posted a video of its working proof of concept on October 20.

Attacks did not wait. Amazon says its MadPot honeypots saw an attempt on October 17 and more from multiple actors on October 21, and that PHP2Shell "is now being broadly exploited in the wild," although "it's unclear if any of these attempts would have succeeded." Cloudflare's Matthew Prince told SecurityWeek it saw "thousands of attempts" in the ten hours before disclosure. watchTowr says the exploits being sprayed so far "either don't work at all, test for timing-based differences, or crash the target," and no source has reported a confirmed compromise. Fake proof-of-concept repositories, some carrying malware, have also appeared on GitHub. Neither CVE is on CISA's KEV catalog as of this writing.

Why it matters if you run public infrastructure

PHP runs a large share of the web: Censys counted about 2.58 million internet-facing PHP hosts, of which roughly 1.57 million were unpatched, per SecurityWeek. Unit 42 puts the number of potentially vulnerable instances at over 22.6 million. VulnCheck counts at least a million on end-of-life versions, which get no official fix. The flaw is in the language runtime, not in your code, so a well-maintained application on an old PHP build is as exposed as a neglected one. Appliances count too: Palo Alto Networks says all PAN-OS and Panorama versions are affected, with fixes still pending, Help Net Security reported. The UK NCSC advises taking any system offline that cannot be fixed right away.

What to check this week

  1. Find every PHP install you expose, including old marketing sites, WordPress installs, admin panels and appliances with a PHP web interface. Run php -v on each server, and check the version used by the web server too, since the CLI and the FPM or Apache module can differ.
  2. Update. Upstream: 8.5.12, 8.4.27, 8.3.36 or 8.2.35. On a distribution package, install your vendor's fixed build (for example Debian DSA-6574-1 for php8.4 and DLA-4848-1 for php8.2). The fixed package may keep the old version number with a new build suffix. PHP warns that the volunteer-run remirepo did not have updates on day one. Restart every PHP worker afterwards.
  3. Plan for PHP 8.1 and older. The PHP project no longer ships releases for them. It published minimal source patches for 7.4, 8.0 and 8.1, and some LTS vendors offer backports. Otherwise, upgrade to a supported version or take the site offline.
  4. If you cannot update today, reduce exposure. PHP's stopgaps "do not make an installation safe," but they block the known paths. For CVE-2026-109618: set memory_limit=-1 where applications cannot override it, and set a low post_max_size (8M without uploads, 32M with). For CVE-2026-109619: set session.upload_progress.enabled=0 (not via ini_set() or .user.ini), and on PHP 8.5 set fatal_error_backtraces=0, then restart every worker. A WAF helps: Cloudflare enabled managed rules for all plans on October 21, and AWS WAF updated its PHP rule group.
  5. Look for signs of attack. Wiz suggests watching for unusual multipart requests followed by memory-limit errors or bursts of HTTP 500s, oversized or malformed PHPSESSID cookies, and unexplained worker restarts. Datadog points to "Allowed memory size ... exhausted" errors reported on "Unknown on line 0," and shells spawned by web server processes.

How Attack Surface Scan covers this

Attack Surface Scan reads the PHP version from the X-Powered-By and Server headers on hosts under your verified domains, including hosts found through certificate transparency logs. Where a version is shown, we match it against NVD's affected ranges for both CVEs. Where the header names a Debian or Ubuntu package build, the distribution's own fix list decides, so a patched package that keeps the old version number is not flagged. Most servers hide the PHP version, and many omit the header entirely. In those cases we cannot tell whether PHP is running or how old it is, and we do not guess. Hiding the header is still good practice, but it is not a fix. We do not send exploit traffic. See Vulnerability matching for the details.

Sources