If you run Apache with mod_php, stop reading and patch now: upgrade to PHP 8.5.12, 8.4.27, 8.3.36 or 8.2.35. PHP released security patches in versions 8.5.12, 8.4.27, 8.3.36 and 8.2.35 for two remote code execution vulnerabilities, GHSA-w8hw-w9fx-j79w and GHSA-6wmf-4rv5-p3rp, found with LLM-assisted vulnerability discovery. The more severe flaw, GHSA-w8hw-w9fx-j79w, lets an attacker write arbitrary memory state that can be read or executed during request shutdown, and a validated exploit targets unpatched Apache with mod_php, where exhausting request memory triggers it before any application code runs; source analysis indicates FPM, FrankenPHP and LSAPI are likely affected as well. The second flaw, GHSA-6wmf-4rv5-p3rp, abuses improper cleanup of worker heap state to poison global state read by INI diagnostics and session upload progress, and both consumers have been shown exploitable against Apache/mod_php. Hello, I spent many years defending a large modern PHP application. The new bugs are bad You should fix them. The runtime will be fine. I promise. Just do it. So, what exactly happened? LLM-assisted vulnerability discovery found some novel applications of memory corruption problems that let you abuse improper cleanup of failed/broken/interrupted web requests. It’s very clever Sometimes, LLMs and humans together do amazing things. GHSA-w8hw-w9fx-j79w - RCE via OOM corruption The really not so good one is GHSA-w8hw-w9fx-j79w https://github.com/php/php-src/security/advisories/GHSA-w8hw-w9fx-j79w , because it lets you write arbitrary memory state into a place where it will be read and potentially executed during request shutdown, a normal part of the PHP request lifecycle. Some common PHP deployment strategies always exercise a shutdown branch before any application code is handled - meaning it does not matter what your application does - if it receives requests it is vulnerable. Due to mod php’s behavior, you can reliably trigger this by simply exhausting request memory. There are a few ways to do this, none of which I will describe to you, but I will tell you that someone with a journeyman familiarity with PHP could figure it out given some breadcrumbs. Apache and mod php unfortunately let this trigger before any application code runs: any PHP application that can receive web requests is exposed. If you are using Apache with mod php you have to fix this NOW; the validated exploit targets unpatched Apache/mod php. Source analysis indicates it is likely that FPM, FrankenPHP, and LSAPI are also affected; PoCs will surface soon if they haven’t already. GHSA-6wmf-4rv5-p3rp - RCE via stale global state Let me be perfectly clear - this bug being harder to exploit does not make it less dangerous. Once somebody does it once, a tool will arise to make replaying that gadget trivial. We have done this dance already with BinaryFormatter et al. Patching is the only defense. I have a somewhat old-school view of bugs that require heap grooming, which is that doing it is hard and gross. LLMs have probably changed the calculus on this a little, but I suspect a skilled operator will do much better than a novice: successful exploits of LLM-assisted heap grooming attacks will be launched by…people who were gonna do it anyway after writing the exploits by hand for months. Therefore, while GHSA-6wmf-4rv5-p3rp https://github.com/php/php-src/security/advisories/GHSA-6wmf-4rv5-p3rp is also Not Good, I am somewhat less worried about it in the short term compared to its evil twin. It is also NEATO and a cool variant of my favorite bug class: insecure deserialization. Basically, it is a language behavior primitive that lets you abuse improper state cleanup to write to global state. This is an incredibly dangerous primitive because it’s related to our first bug via the request lifecycle. A PHP worker has its own memory heap, and as part of normal behavior zeroes it out when it dies. Except for when it doesn’t. This is a Producer of a potentially hazardous state. A PHP worker has its own memory heap, and as part of normal behavior zeroes it out on initialization before it ever reads from it. Except for when it doesn't. This is a Consumer of potentially hazardous state. This is akin to a deserialization gadget - functionality that allows Bad Things To Happen. There are two known consumers of potentially poisoned state: INI diagnostics and session upload progress. Some runtimes, like mod php, also do things like read php.ini once on startup then persist forever. This is Very Super Not Good if you can, you know, use a known producer to write arbitrary stuff to that state. This bug is harder to exploit . Both the producer and the consumer must reside in the same worker. Both consumer types have been shown to be exploitable vs Apache/mod php, and session upload progress has been shown to be exploitable against Apache/mod php and FPM. It’s probable that we’ll end up finding exploitable cases in FrankenPHP and LSAPI too. This is how it is now. Weird edge case “you’d need to be clairvoyant to…” bugs are getting unearthed. There will be more. What to do and what we’re doing What to do now: upgrade to PHP 8.5.12, 8.4.27, 8.3.36 or 8.2.35. On end-of-life 8.1, 8.0 or 7.4, apply the available backports and then immediately plan an upgrade - do not depend on cherry-picked commits for bugs in core runtimes, ever . While you are upgrading there are partial mitigations such as setting session.upload progress.enabled=0 and leveraging relevant firewall rules which attempt to block known payloads however this is not a strategy we recommend to rely on as both can be bypassed. What we’re doing: Semgrep Guardian https://semgrep.dev/products/semgrep-guardian/ now flags vulnerable PHP versions when your agent starts working on a project, and coverage for source-code defined usages of PHP is on the way.