PHP 8.5.12, 8.4.27, 8.3.36 and 8.2.35 shipped on October 21 at 14:00 UTC to fix two bugs that give an unauthenticated attacker code execution on any web server running PHP. Both carry a CVSS 4.0 score of 9.2. The vulnerable code dates to PHP 5.4.0, released in 2012. Governments in Finland, the Netherlands, Australia and Canada pulled sites offline rather than wait for packages, and the NSA told organizations to patch or unplug. If you run PHP anywhere that takes requests from the internet, update first and read this after.

Two bugs, one trigger

Both bugs live in how PHP handles fatal errors, out of memory errors in particular. When a request crosses memory_limit, PHP bails out of native code with longjmp() and skips the cleanup that code expected to run. CVE-2026-109618 is the case where request data is left half initialized and the cleanup path then treats it as valid. CVE-2026-109619 is the case where a global still points at memory from the previous request, and the next request on the same worker follows that pointer before initialization resets it. A use-after-free either way. The PHP advisory has the full breakdown.

Every known trigger is a multipart/form-data request. PHP parses multipart bodies at request startup, before the application loads, and the session upload progress handler runs in that same window. Wiz Research showed the handler will URL-encode freed heap memory into a PHPSESSID response cookie on the next request. That heap can hold other users' passwords, tokens, API keys and, per Sansec, TLS private keys. The application never has to call session_start(). A Hello World script on a vulnerable PHP leaks worker memory.

Apache with mod_php is the worst position. The advisory says a demonstrated exploit fires before any application code runs. PHP-FPM blocks one of the OOM paths at startup, but the security team confirmed RCE against FPM through application code paths, and Sansec confirmed unauthenticated RCE on Magento 2.4.9, WordPress, Drupal, Joomla and seven other applications. php-cgi, FrankenPHP and LiteSpeed are on the affected list too.

The first clue was two years old

The PHP Foundation's own write-up is the most candid part of this story. In 2024 PHP got its first external audit in years, run through OSTIF, paid for by Germany's Sovereign Tech Agency and performed by Quarkslab. While a core developer under contract to the Foundation fixed one of the Quarkslab findings, they found the first signs of the OOM problem. An exploit was theorized. Nobody found a concrete vector.

Then it sat. Each candidate fix had a cost: a backward compatibility break, a new denial of service path, or changes to a large number of third-party extensions. The security team runs on consensus and has few people. The Foundation's words: "the delay was a structural failure."

Outside auditors with LLMs broke the stall. Calif started an audit of PHP on July 30 under OpenAI's Patch the Planet program, using GPT-5.6 Sol. On August 11, Calif reported an unconditional RCE with the same root cause as the 2024 finding. OpenAI reported the same root cause the same day. Wiz found the bugs independently on August 19, had unauthenticated RCE against Drupal on August 20 and WordPress on August 21, and reported on August 24, using Gemini 4 Argon and GPT-5.6 Sol alongside its own tooling. Wiz says one researcher did in about a week what a team would have needed months for. OpenAI added more vectors on September 18.

I don't take vendor claims about AI at face value, and both OpenAI and Google have a product to sell here. But the dates are the dates. A problem the maintainers knew about for two years went from "theorized" to "working exploit against WordPress" in three days once someone pointed a model and a researcher at it. The models mattered less than the hours. A memory safety question stayed open for two years because nobody was paid to close it.

The embargo broke three times

The release was planned for October 22. On October 20 around 15:00 UTC the two CVE IDs started circulating on forums with a wrong release time and a wrong CVSS score of 10.0. PHP posted its advance notice at 19:30 UTC and moved the release up a day. Around 20:00 UTC, Calif mistakenly published a video of its proof of concept running against several targets. Copies spread and, by the Foundation's account, sped up exploit development. Around 23:00 UTC, mitigation advice shared privately with critical infrastructure providers appears to have leaked as well.

Then at 07:41 UTC on October 21, Chainguard published container images containing the fix, more than six hours before the coordinated release. Anyone with a disassembler could diff the binaries. Patchstack had exploitation reports from hosting partners by 07:34 UTC. Cloudflare had WAF rules live by 03:02 UTC and reported attack traffic against customers before disclosure, with attackers mutating payloads to get around the rules. Cloudflare did not publish counts.

Coordinated disclosure for a runtime behind 70% of websites (the figure is Wiz's, and it is in line with what W3Techs has reported for years) involves distributions, LTS vendors, cloud providers, CDNs and the researchers themselves. The PHP team held its end. Three different outside parties did not. I don't see a process fix for that beyond shorter embargoes, and shorter embargoes punish the distributions that need packaging time.

Patch order for operators

  1. Update to 8.5.12, 8.4.27, 8.3.36 or 8.2.35 from your distribution, or build from source. Distributions and LTS vendors got patches in advance. The volunteer Remi repository had nothing on October 21, so if that is your source, switch to distro packages or build.
  2. If you are on 7.4, 8.0 or 8.1, the security team posted minimal source backports in branches named PHP-<version>-CVE-2026-109618-109619. That is a courtesy, not support. 8.2 itself goes end of life on December 31, 2026.
  3. Restart every worker after the change. An FPM pool that has been up for months is still running the old binary.
  4. Check who owns the runtime. Laravel Forge's automatic security updates do not touch PHP. Managed WordPress hosts vary. Ask.

The mitigations are partial and the advisory says so. Setting session.upload_progress.enabled=0 in php.ini or the pool config (not ini_set, not .user.ini) and restarting closes the confirmed session path for CVE-2026-109619 and nothing for CVE-2026-109618. On 8.5, fatal_error_backtraces=0 closes one more path. For the OOM bug, the advice is memory_limit=-1 set through php_admin_value so nothing can override it, plus a low post_max_size and request limits at the proxy. Removing the memory cap means one request can eat the box, so pair it with a cgroup limit, and do not use RLIMIT_AS or RLIMIT_DATA, since those trigger the exact allocation failure the bug needs.

Maintenance mode in WordPress or Magento does nothing here, because PHP parses the request before the application sees it. If you can't patch yet, the options are stopping PHP-FPM behind a static page, or rejecting multipart/form-data at nginx or Apache and accepting that uploads break until you are done.

Volker Dusch, the Foundation's AI security engineer, told the Wall Street Journal this is the worst problem PHP has faced in over a decade and compared it to Heartbleed. The comparison holds on reach and on the fact that the bug was in every default install. It differs in one way that does not favor PHP: Heartbleed went from private report to patch in about a week, while this one had a head start of two years that the maintainers knew about. The Foundation says security decisions will now go to majority vote instead of consensus, with leadership pulled in earlier. Since July 1 the team has published 15 CVEs and worked through more than 100 invalid or duplicate reports, and it is asking hosting providers and governments for money.

My guess is the next month of incident reports will be dominated by shared hosting boxes running 7.4 on mod_php that nobody has logged into since 2022. The patch is out. The hard part is the inventory.