Well, here we go again. Except this one wasn’t just another vulnerability. If you run anything on PHP, you’ve probably already heard about PHP2Shell. But let me recap it concisely:
- Two critical bugs in PHP itself, CVE-2026-109618 (RCE via out-of-memory corruption) and CVE-2026-109619 (RCE via stale global state), were patched on October 21st in PHP 8.5.12, 8.4.27, 8.3.36, and 8.2.35.
- Both allow unauthenticated remote code execution. On Apache with mod_php, a single request can trigger the attack before any of your application code even runs. According to Wiz, every PHP version going back to 5.4 is affected by at least one of them.
- On October 26th, CISA added both to its Known Exploited Vulnerabilities catalog, which means they’ve been seen exploited in the wild.
- As a bonus, a separate and much less likely issue, CVE-2026-115560, was announced two days later. The fix for now is setting
session.upload_progress.enabled=0until the next regular release.
I had several servers to update. I got them all patched the same day and I saw no evidence of any attack attempts in the logs. So for me personally, it wasn’t that big of a deal. But it was still a scary event. I was able to patch fast because I knew exactly which servers were running PHP and could act on it immediately. Plenty of organizations can’t say that. And within five days, attackers were already using these in the wild.
The foundation is thinner than you think
PHP may underpin up to 70% of websites. WordPress, Drupal, Joomla, MediaWiki, the list goes on. So how big is the team behind it? The PHP Foundation has one full-time staff member, its Executive Director, and 14 mostly part-time contractors. The whole thing runs on roughly $1M a year.
This exposes a long time weakness in software. So much of modern software is built on top of free, open source code that is maintained by individuals or extremely small teams. Corporations build billion dollar businesses on top of it, and then they aren’t paying their fair share.
To be fair, it’s not that nobody helps. It’s that relying on donations for critical infrastructure doesn’t work. Imagine if your town’s fire department was funded purely by voluntary donations. Every household assumes the neighbors will chip in, so skipping this year won’t hurt anything. Repeat that over and over and it adds up, right up until the day there’s a fire and no truck shows up. Economists call this the free-rider problem, and open source has it bad.
The numbers back it up. In 2025, the number of PHP Foundation sponsors dropped to 536, which the foundation described as “substantially less than the previous year.” Expenses were about $784k. Donations received were about $645k. That math doesn’t work for long.
That being said, I do want to give credit where it’s due. These are the largest organizational contributors on the foundation’s Open Collective since 2021:
- Automattic, about $762k
- JetBrains, about $477k (and they also sponsor the Executive Director)
- Sovereign Tech Fund, about $214k
- The Linux Foundation, about $184k
- Private Packagist and Craft CMS, about $90k each
These companies are keeping PHP afloat. We could use a lot more like them. It’s worth noting the Sovereign Tech Fund is a German government program, which kind of proves the point. Public infrastructure needs public-style funding. And Chainguard just gave $50k this month, right after PHP2Shell. That’s great, but it also shows the pattern. Companies tend to pay after the fire, not before it.
The black light
Here’s the part I find really interesting. These bugs weren’t new. Stefan Esser found the first PHP memory limit vulnerability back in 2004. A related bug was reported in 2020. In 2024, an audit identified another related issue, but nobody could prove it was actually exploitable, so it sat there. Then in August 2026, three separate teams, Calif, OpenAI, and Wiz, all found working exploits within weeks of each other. All three were using AI.
Wiz put it well: demonstrating exploitability “required an exceptionally complex chain of steps, at the edge of what human researchers could practically achieve.” AI is really good at tedious work. Most of these chains are things most of us never would have had the patience to try. Maybe someone would have gotten there by accident or chance, but most likely not.
I compare it to the invention of the black light. The stains were always on the wall. Some of us could even see faint outlines. But now we can see exactly what’s there, and it’s a bit shocking.
It’s going to get worse before it gets better
I wrote about the Axios supply chain attack back in April, and unfortunately I think this is going to keep getting worse before it gets better. We’ve got decades of hidden bugs and we just turned the lights on.
It’s already showing up in the numbers. OpenSSL went from about 9 security reports a month to 108 in August. Out of roughly 500 reports over the past year, only 63 turned into actual disclosed vulnerabilities. And every single one of the other ~440 still needed a human to review it. cURL ended its bug bounty entirely because AI slop was overwhelming the team.
But here’s the good news. We can finally tackle the security issues we’ve been putting off for decades. This is a case where AI can actually make software better, precisely because attacking is easier. If attacking is easier, the only way to proceed is to fortify. Firms that keep treating security as a nice to have are about to find out how expensive that is.
Output is cheap, verification is the bottleneck
This isn’t just about bugs. It’s cheaper than ever to produce vast amounts of output. Bug reports, pull requests, articles, comments, you name it. Our bottleneck isn’t producing anymore, it’s consuming and classifying.
I see informational warfare as a battle of attrition. Overwhelm your opponent until they stop verifying. At that point one of two things happens. Either they shut down, and you just pulled off a successful DoS attack. Or they start blindly accepting input as good, and now you have an in to the system.
flowchart LR
Flood["10,000 low-quality reports"] --> Inbox[Single inbox]
Gem["1 critical report"] --> Inbox
Inbox --> Reviewer[Overwhelmed reviewer]
Reviewer --> Outcome{"Gives up or rubber-stamps"}
That one critical report is stuck in the same line as everything else. We have to improve our defense systems.
What we can do about it
Some of this is straightforward:
- Fund the maintainers. If your business depends on an open source project, pay in proportion to how much you depend on it.
- Audit your own stack with AI before attackers do. The same tools that found PHP2Shell are available to you.
- Know where your stuff runs and patch fast. Same day patching only worked for me because I already knew which servers ran PHP.
- Raise the bar on reports. The CNCF guidance is a good start: publish a threat model, require a working proof of concept, and have a human review it before it gets submitted.
The harder part is the filtering problem, and this is where I’ve been spending most of my thinking.
This isn’t completely unknown territory. Bitcoin already had to solve a version of it. How do you stop someone from flooding a network with fake identities or votes? Proof of work. Make participation cost something. And proof of work itself came from Hashcash, which Adam Back proposed in 1997 to fight email spam by making every message cost a little bit of compute. Cheap for one email, expensive for a million.
It’s largely inefficient and probably not the solution here though. It taxes honest people just as much as attackers. Well funded attackers can just pay the cost. And it proves effort, not quality. But it does show there are two levers. You can make producing input expensive, or you can make classifying it cheap. AI pushed the cost of producing input to nearly zero, so classifying is the lever we’ve got left. Email actually went through this already. Spam filters plus sender reputation turned into the inbox, promotions, and spam folders we all use today.
Which brings me to digital reputation. Some crypto coins use reputation as the authority to confirm transactions. In the AI world, I think we want something similar. Separate things into channels. You can have high trust channels with people we know well who have earned more authority, and lower trust channels that get more scrutiny. A maintainer could fast track reports from known researchers and send anonymous AI generated reports through stricter checks.
The way I think about it, this is basically an implementation of MapReduce. We’re taking a large amount of data, running it through classifiers, and splitting it into channels. Once it’s routed to the right channel, we can pick it off as needed.
flowchart LR
Input[Incoming firehose] --> mapStage
subgraph mapStage [Map: classify each item]
C1[Classifier]
C2[Classifier]
C3[Classifier]
end
mapStage --> shuffleStage
subgraph shuffleStage [Shuffle: route by channel]
High[High trust]
Medium[Medium trust]
Low[Low trust or unknown]
end
High --> FastReview[Reviewed first]
Medium --> NormalReview[Reviewed as time allows]
Low --> StrictReview["Stricter checks<br>PoC required<br>Rate limited"]
The last step isn’t really a “reduce.” Each channel gets consumed on its own, at its own pace, with its own capacity. And that’s the whole point. A flood of low quality info in one channel can’t block out the info from a high quality source, because they’re no longer waiting in the same line.
Reputation also has to be earned and lost over time. Every review outcome feeds back into how the next submission from that source gets routed.
flowchart LR
Source[Source submits] --> Classifier["Classifier +<br>reputation lookup"]
Classifier --> Channel[Assigned channel]
Channel --> Review[Human or AI review]
Review -->|"Valid finding"| Up[Reputation increases]
Review -->|"Slop or invalid"| Down[Reputation decreases]
Up --> Ledger[Reputation ledger]
Down --> Ledger
Ledger --> Classifier
Now for the caveats, because this isn’t a silver bullet.
High trust channels are exactly where a stolen or farmed identity does the most damage. The Axios attack used a trusted maintainer’s stolen credentials. The xz utils backdoor came from someone who spent years building up trust before slipping it in. So high trust input still gets verified, just more lightly. And the moment a high trust channel exists, attackers will start optimizing to look high trust.
On the other end, the low trust channel can’t become a black hole. Unknown people find critical bugs all the time. There has to be a path for a newcomer to earn trust.
And that leads to the real problem. Reputation still needs a way to judge quality. Otherwise it turns into a popularity contest, an old boys’ club, or something attackers can farm. To be honest, that’s a non-trivial question and one I don’t fully have the answer to. But it’s one I’m thinking about a lot.
The black light is on. We can’t unsee what’s on the walls. Now we have to actually clean them.
