On October 21, I woke up to a message telling me there was a critical PHP vulnerability. When I read up on that, I learnt that this was indeed Scary Stuff™, that would allow a hacker to use PHP2Shell to remotely execute code on a host, thereby essentially taking control of that host.
It turns out that this vulnerability has been in the code ever since PHP 5 (which is around 10 years old now), and was only found when Wiz and OpenAI decided to use an AI agent to test that code for vulnerabilities.
This was then reported to the people at the PHP Foundation.
Then the disclosure got away from everyone: a company called Chainguard unilaterally broke the embargo at 07:41 UTC. Details leaked more than two days before the planned release, and PHP pulled its schedule forward to stay ahead of attackers.
Needless to say, Chainguard (imo deservedly) caught a shitload of criticism for that.
Now, it just so happens that a security researcher in 2024 found the first signs of a flaw that led to one of the vulnerabilities, but that the issue was “theorized, but no concrete vectors were found and other concrete issues with clear impact overshadowed these concerns.” (source: US News)
The “Out of Memory is a Death Sentence” Philosophy
For 22 years, the foundational architecture of the PHP core engine treated a fatal Out of Memory (OOM) error or execution timeout as an unrecoverable “nuclear option.” When PHP hits a memory limit, the core immediately halts what it’s doing, throws a fatal error, skips traditional object cleanup, and runs zend_bailout() to forcefully wipe the request heap.
For years, part of the development team argued that this was completely safe. Their logic was: “The request is dead, the memory is freed, and the worker process is going to handle the next request from a blank slate. Why waste CPU performance adding safety checks for a dead request?” (source: wiz.io)
However, researchers proved that the memory wasn’t always sufficiently freed. Because modern production environments use worker-based architectures like PHP-FPM or Apache’s prefork, a single persistent worker process handles multiple web requests in a row to save system resources. In the case of a request that is killed mid-operation, global pointers, aiming at memory addresses toat PHP just freed, are left dangling.
For two years, the developers couldn’t agree on how this issue should be addressed. And then, late summer 2026, AI code scanners, using OpenAI and Anthropic, independently discovered the exact same exploitation paths and researchers weaponized it into the unauthenticated “PHP2Shell“ tool (source: Datadog Security Labs).
The PHP Foundation has admitted publicly that they consider this a “structural failure”.
Yes, that woke me up like a bucket of espresso.
Why did this have so much impact?
PHP dates back to 1995. It was written by Rasmus Lerdorf, who wrote it as a tool to manage his personal web site. Rasmus never intended PHP to become a programming language, but it grew organically.
Over time, various people started to add functionality to it. As a programming language, it had a reputation of bare adequacy, and wasn’t considered a serious programming language for a long time. The majority of security issues related to PHP code were caused by careless programming.
But it turned out that it was well-suited to server-side web development. On top of that, support was widespread, so once the language got more capable, it really took off.
WordPress (which powers the majority of the web servers, including this one) is written in PHP.
Estimates are that PHP powers approximately 70% of all web servers on this planet.
So yeah… when PHP goes down, it’ll get pretty quiet on the Internet.
How to proceed
The idea was that a patch fixing this issue would be released into the world at around 14:00 UTC (that’s 16:00 in CET, where I live). But everyone who understands this, will realise that malicious hackers would be eager to review the patch, because when they knew what the fix was, they could find un-patched installations and use the exploit.
So, many press outlets were talking about “a race with the clock”, because you HAD to patch PHP before an attacker would try to break in.
Luckily, the situation wasn’t as dire as that.
The first thing to do was, of course, gracefully stop PHP — if PHP isn’t running, the attack vector is gone.
For good measure, I decided to follow this up with a reboot — just because the fact that I’m paranoid does not exclude the possibility that they (stale pointers) are out to get me, and a reboot is the surest way to do garbage collection.
This, of course, meant that WordPress (which serves a couple web sites I manage, including the one you’re reading now) was nonexistent, so I put a plain static HTML page in place informing people that we would be down for awhile.
From that point onward, I was safe, and I could download the patch at my leisure when it would become available.
The poor web site that was serving up the patch when it did become available at around 13:50 UTC was completely overwhelmed. One of my servers sneaked through and got the patch straightaway, but the other two kept getting timeouts. So I decided to postpone that to after dinner, but it was still flaky. The last server (which doesn’t do anything useful anyway) was only updated this morning at around 8:00 UTC.
Web sites managed by me are all safe:
this site
vanderster.net
waarder.online
dorpsteam.waarder.online
Leave a Reply