,

php2shell Went From Leak to Exploit in less than 90 Minutes

When the PHP team shipped the php2shell fixes on Oct. 21, every advisory ended the same way: patch now, because nothing else is a real fix. That is an unusual thing for a security advisory to admit, and it is…

php2shell is two unauthenticated remote code execution (RCE) flaws in the PHP runtime itself: CVE-2026-109618, a memory corruption during request startup, and CVE-2026-109619, a use-after-free (UAF) that reuses freed memory left behind by an earlier request. Both rate CVSS 9.2, both fire before any application code runs, and both reach every way PHP serves web traffic: mod_php, PHP-FPM, php-cgi, FrankenPHP, and LiteSpeed. The fixed releases are 8.2.35, 8.3.36, 8.4.27, and 8.5.12. Everything from 5.4 up to 8.5.11 is exposed.

A working exploit existed about 90 minutes after the details leaked, the kind of weaponization that used to take a skilled team weeks. By the time most teams had finished reading the advisory, security researchers were already reporting exploitation attempts against live servers, though no confirmed compromise yet.

Why There’s No Clean Check

Most vulnerabilities give you a safe way to ask “am I exploitable?” A SQL injection answers a time-based query. A server-side request forgery calls back to a host you control. php2shell offers nothing like that, because the event that would confirm it is the same event that corrupts the worker. The confirming request and the damaging request are the same request. So the only honest signal left is the version of PHP a server is actually running.

That signal is slippery. Plenty of well-run servers set expose_php off, so the version never appears in a response header at all. The ones that do expose it often report a distribution package string, and distributions backport security fixes onto an old version number, so “8.3.12” from one vendor can be patched while the identical number from upstream is not.

What We Did About It

Within hours of the advisory, Xora was running php2shell checks across every application we scan, at no charge and without anyone asking. The check is not the clever part: it reads the PHP version a deployment is running and compares it against the fixed releases, the same thing a careful operator would do by hand. What mattered was that it was already wired into every scan we run, so the moment the advisory was real we could sweep the whole fleet at once and flag exposure across it, rapidly notifying our customer base.

Where it found a PHP runtime in the vulnerable range, it raised the finding in that customer’s dashboard and emailed the owners. We kept those findings honest about what the evidence supports: a floating base image can be patched or exposed depending on when it was last rebuilt, so most of what we sent tells the customer they are likely exposed and asks them to confirm the patch level, not that they are breached.

What It Doesn’t Do

It does not prove the bug at runtime. Proving php2shell means sending the request that crashes the worker, and we will not do that to a live system to win an argument the version already settles. That ceiling is deliberate: the detector gives you a grounded version judgment, not a demonstrated exploit, and it reports one runtime finding per application rather than walking every service behind it.

If you run PHP, the move is the one the advisory already named: get to 8.2.35, 8.3.36, 8.4.27, or 8.5.12. Everything short of that is a way to spend time you do not need to spend.


Leave a Reply

Discover more from Xora

Subscribe now to keep reading and get access to the full archive.

Continue reading