php2shell is not frightening because the name is new; it is frightening because of its blast radius. Two remote code execution vulnerabilities in PHP core (CVE-2026-109618 and CVE-2026-109619) have been hiding in code paths that date back to the PHP 5.4 era for 14 years, and anyone can run arbitrary programs on your server without logging in. This post walks through the mechanism, the role AI played in the hunt, the 71-day patching window, the global exposure, and the four things an ordinary site owner should do today.


1. Three Countries Hit Pause on the Night of October 21

The timeline starts at around 10 p.m. Japan local time on October 21. Japanese Prime Minister Sanae Takaichi posted a message whose first word was “Urgent”: PHP has two critical vulnerabilities, patches would ship at 23:00 that night, and if you run a PHP website you should be ready to patch immediately — if you cannot, take the site down first. The message passed 48 million views across social platforms.

The emergency announcement on the night of October 21: two critical vulnerabilities, patches at 23:00 that night, and take your site offline if you cannot patch in time

Within two hours, the US NSA and FBI said essentially the same thing: update if you can, go offline if you cannot.

The NSA and FBI recommendation: update if you can, take the site offline if you cannot

The Netherlands was even more direct — government sites, the portals of several major institutions, and even a few hospital websites were simply taken down. Finland’s government sites did the same.

What made so many countries nervous at once was a programming language born in 1994. Programmers have always joked about it as “the best language in the world”. This time, however, what was dug up was not some WordPress plugin. It was the language itself.

2. How Much Does PHP Matter? It Runs the Backend of 70% of Websites

PHP started life as a set of small tools written by Rasmus Lerdorf to count how many people viewed his résumé; the name came from “Personal Home Page Tools”. It later became a language dedicated to building websites. WordPress runs on it, Facebook was once built on a massive PHP system, and the company even built a faster engine specifically for it.

W3Techs statistics: roughly 70% of sites with an identifiable backend language run PHP

W3Techs puts it this way: among sites where the server-side language can be identified, PHP accounts for about 69.3%. The “70% of all websites use PHP” line you see in the news is exaggerated, but even by that conservative measure PHP underpins a very large slice of the internet.

That fact defines the nature of this incident: the problem is not how good your application code is, it is the runtime underneath it.

3. What the php2shell Vulnerabilities Look Like: Both Holes Sit in the Cleanup Path

You do not need to dig into the code to understand the shape of it. For every request, PHP prepares data, and once the request is handled it cleans that data up so the next request is not affected by leftovers. Both holes appear in that cleanup stage.

Vulnerability Trigger Impact
CVE-2026-109618 (OOM corruption) The request hits the memory limit and gets cut off; cleanup then treats partially initialized data as valid The array key insertion path is corrupted, the function pointer table becomes attacker-controlled, and it lands directly on remote code execution
CVE-2026-109619 (stale global state) A request hits a fatal error and the global state is never reset, so the next request reads the previous request’s leftovers A cross-request use-after-free that crashes the worker; the official advisory also confirms memory disclosure

Concretely, the attack chain looks like this: craft a multipart request that declares no Content-Length and nests a file upload without a filename. PHP still allocates arrays for the file metadata, memory runs out fast, and you get an OOM. After the OOM, PHP calls zend_bailout(), which does a longjmp() straight out — while other C code is still working on that memory region. That region is then treated as a legitimate object later on, which is a textbook use-after-free. As a bonus, the same path can encode heap memory into the PHPSESSID cookie and hand it back to the attacker; leaked heap addresses can then be used to bypass ASLR.

Both holes scored 9.2 out of 10, and PHP published its advance notice a day early

Both vulnerabilities carry a CVSS v4.0 score of 9.2. One widely repeated claim needs correcting: the “10.0” that circulated when the CVE identifiers leaked is wrong — the official score from the PHP security team is 9.2 (see the official PHP security advisory). Security firm watchTowr puts it even more bluntly — even if your site is a single line of “Hello World”, you can still be attacked, because the defect lives in PHP itself, and no amount of good code on your side helps.

The exposure is not limited to one deployment model: PHP-FPM, Apache mod_php, php-cgi, FrankenPHP and LiteSpeed are all in scope, and mod_php is the worst of them, because an unauthenticated request can trigger it before any of your own application code runs.

4. A 14-Year-Old Debt: Why Was It So Hard to Trigger?

The earliest affected code path traces back to PHP 5.4.0, which means 2012. Nobody reported it for 14 years not because it was obscure, but because it was so hard to trigger reliably.

People did notice the cracks back in 2024. The PHP Foundation, funded through the Sovereign Tech Agency and organized with OSTIF, brought in Quarkslab for the project’s first external security audit in years. While fixing one of the issues Quarkslab reported, a core developer found the first signs of the OOM problem behind CVE-2026-109618 — but at that point they could only suspect it might be exploitable; there was no concrete attack path. Every candidate fix came with side effects: some broke backward compatibility, some introduced new denial-of-service risk, and others required changes across a large ecosystem of third-party extensions that seemed impossible to coordinate. With no evidence that it was genuinely dangerous, and with the handful of core developers who actually understand the engine already buried in other work, the decision-making ground on itself and the fix stalled. The PHP Foundation’s own post-mortem puts it bluntly: this was a structural failure, caused by both the security team’s decision process and its lack of resources.

The cracks were visible back in 2024, but there was no concrete attack path to prove them

5. AI Compressed the Hunt From “Over a Decade” to “Days”

By 2026, the pace had changed completely.

  • July 30: security firm Calif entered through OpenAI’s Patch the Planet program and began auditing PHP.
  • August 11: researcher Ryan A at Calif reported an unconditional remote code execution sharing the same root cause as the OOM problem found in 2024; OpenAI independently reported the same root cause, Wiz added further attack vectors on August 24, and OpenAI supplied new vectors again on September 18.
  • From August: as of August 11, fixing this became the top priority of the entire PHP Foundation security team; Trail of Bits later joined the PHP audit effort too.
  • October 20, afternoon: the vulnerability identifiers began circulating on Hacker News and social media.
  • October 21, 14:00 UTC: patches shipped, ahead of schedule.

Calif confirmed unauthenticated remote code execution against major PHP applications including WordPress, Drupal, Joomla and Magento. The PHP Foundation publicly credited Calif, OpenAI, Wiz, Trail of Bits, OSTIF and Quarkslab, and these teams have stated that they used large models in their research. The full technical write-up by the independent researcher at Calif is at calif.io/php2shell.

So the claim that “AI found in days what humans missed for over a decade” is half right. Humans did see the cracks back in 2024 — they just could not prove how dangerous it was. The real contribution of AI is not that it “found a potential issue”; it is that it turned the issue directly into a reproducible, weaponizable exploit chain. That step used to require an expert to build by hand; now it takes days to produce a demo video.

That is the point I would keep: AI did not just make finding vulnerabilities faster, it collapsed the cost of proving how dangerous a bug actually is. Once verification gets cheap, the rate at which vulnerabilities come out rises with it.

6. Seventy-One Days: Why the Fix Took So Long

From the August 11 report to the October 21 release, exactly 71 days passed. OpenAI’s explanation is direct: fixing this vulnerability is extremely difficult and requires substantial re-engineering of PHP core. In its release post, the PHP Foundation also admits this was a structural failure rather than one person’s oversight.

From report to patch: 71 days in between

The more realistic constraint is people. Only four developers are credited in the official advisory, and this was far from the only thing on their plate:

Only 4 credited fixers, plus 15 vulnerabilities handled since July and 100+ invalid reports

Number Meaning
4 Developers credited with the fix
15 Vulnerabilities publicly handled since July alone
100+ Reports reviewed, most of them invalid, duplicate or not reproducible

AI did help on the fixing side too: the PHP Foundation worked with Alpha-Omega to scan PHP with Anthropic’s Claude Mythos, then brought in OpenAI’s Daybreak Red to validate reports and exploit chains, with models also used to group and deduplicate incoming reports. But the Foundation’s own wording is that every call and every patch is still made by a human. Deciding which side effects are acceptable, and who signs off on them, still falls to those same few people. Running more models does not solve that.

7. The Leak Two Days Early: How Coordinated Disclosure Broke

The standard playbook is simple: hand the patch privately to distribution maintainers, agree on a single global moment, and let everyone patch simultaneously. This time the date was set for October 22.

The result leaked two days early

Around 15:00 UTC on October 20, the two CVE identifiers began circulating, and they came bundled with a wrong release time and a wrong CVSS score of 10.0 (the real score is 9.2) — though no technical details leaked. PHP published its advance notice at 19:30 UTC that same evening and moved the release from October 22, 14:00 UTC forward to October 21, 14:00 UTC. One of the reporting teams then mistakenly published a demo video; even though it was deleted, copies kept circulating on social media, which accelerated the spread of various proofs of concept.

A more painful moment came the next morning: at 07:41 UTC on October 21 — more than six hours before the coordinated release — Chainguard unilaterally broke the embargo and published built images containing the fix. Other PHP users were still waiting for the release, and attackers could already study the fix in binary form.

When the official patch shipped, less than a day had passed since the identifiers leaked. So, had anyone already moved?

The Foundation saw nothing; Cloudflare saw attack traffic; honeypot servers saw exploitation attempts

  • PHP Foundation: no usable exploit code had been observed when the patch shipped.
  • US cybersecurity agency: no attacks observed, but attack traffic was detected.
  • Security firms: exploitation attempts were observed against their honeypot servers.
  • Amazon Threat Intelligence: an exploitation attempt was already visible in its honeypot network on October 17, four days before public disclosure — and it recommends starting investigations from October 17, not from the disclosure date.

“Someone tried” is not the same as “someone succeeded”. But it does mean people were already watching.

8. How Big Is the Exposure? Why “Take It Offline” Is Not a Joke

Put a few numbers side by side and the scale becomes obvious:

  • Shodan: more than 1.9 million publicly reachable hosts run PHP.
  • Researchers’ rough estimate: more than 1.3 million publicly exposed hosts are potentially vulnerable.
  • One security platform’s internet-wide estimate: among servers where the PHP version can be identified, the number running unsupported versions is about 2.8 times the number running supported ones.

That last one is the worst. PHP 8.1 and earlier stopped receiving official updates long ago; the Foundation published source backports for a few of those branches, but you have to compile them yourself — they are not drop-in. Older branches did not even get that.

Find the bug → 71 days to fix → the patch leaks early → roll it out machine by machine, and nobody knows how long the last step takes

This is exactly why everyone from the Japanese Prime Minister to the NSA and FBI landed on the same advice: if you cannot keep up, step aside for now. That is not cowardice, it is the least luck-dependent strategy available today. The official position is equally clear — there is currently no complete solution, and updating is the only safe option. The rumor circulating online that “tweaking the upload-related settings blocks it” only closes one path, and several follow-up analyses have already corrected that claim.

Interim mitigations (partial coverage only, not a complete fix):

Mitigation What it covers Caveat
memory_limit=-1 Blocks the OOM trigger path for CVE-2026-109618 Applications must not be able to override the setting
session.upload_progress.enabled=0 Tightens one exploitation chain for CVE-2026-109619 All PHP workers must be restarted after the change
fatal_error_backtraces=0 (PHP 8.5) Reduces the poisonable backtrace kept in global state The switch only exists on 8.5
Container / cgroup memory limits Provides an availability boundary The official guidance says this is not a complete mitigation either
WAF rules Cloudflare has shipped rules to every customer, including the free tier Officially described as a stopgap, and it only covers traffic routed through Cloudflare

CERT-EU goes further: organizations that cannot update right away should consider isolating internet-facing applications from public networks.

9. The Side Effects on the Bug Bounty Economy

Getting paid for finding bugs is the basic logic that has kept this industry running for decades. But once the marginal cost of finding bugs collapses toward zero, the other side shows up too.

End of March: the HackerOne open-source bounty program paused new submissions

  • Google VRP: from October 2, it stopped accepting vulnerability submissions for open-source products, citing a surge in automated submissions, the vast majority of them invalid.
  • curl: in January 2026, the maintainer simply shut down its HackerOne bounty program after a flood of AI-generated invalid reports.
  • HackerOne’s Internet Bug Bounty: paused for new submissions effective March 27, for the same reason — AI makes vulnerabilities appear faster and in greater numbers, and open source cannot keep up with fixing them.

The Google VRP notice: automated submissions surged and the vast majority were not valid vulnerabilities

This is the same phenomenon as those 100-plus invalid reports on PHP, and that was only the subset of people willing to report.

The other side is the attackers. On October 17, the open-source AI coding tool OpenCode disclosed a breach affecting roughly 1.4% of its Console users, with API keys for OpenAI, Anthropic and Gemini stored in user workspaces exposed and harvested for large-scale model distillation attacks; some users saw thousands of dollars in charges wiped overnight. The developers said the attack ran for 48 hours and used AI agents — and joked that they now basically need their own agent watching, around the clock, for people who find bugs and do not report them.

10. The Four Things an Ordinary Site Owner Should Do Today

If you run a website, or if you built something with AI, pin down these four things first:

Pin down four things: the PHP version, who owns the upgrade, whether you can go offline, and whether anyone already got in

  1. Which PHP version is underneath? The PHP version, not the WordPress version. Plenty of products do not look like they run PHP while it is running in the background.
  2. Who owns the upgrade? Has the platform already patched it for you, or do you package and manage it yourself? After upgrading, restart the PHP workers and confirm that the version actually running is the new one.
  3. If you genuinely cannot patch, can you take it offline? Isolation is safer than exposure.
  4. Has anyone already gotten in? Look for extra files in the web root and for unknown administrator accounts — AI can do this work for you now.

Two hours after the official announcement, OpenAI posted a follow-up: point Codex at the openai/php2shell-checker repository and it will walk you through the check — with server access you inspect the PHP configuration on the server directly, with only a URL you go through the site.

Two hours after the announcement OpenAI added a post: point Codex at openai/php2shell-checker

But two traps must be known: the tool only checks the version number. If a site hides its version, all it will tell you is “unknown” — and the repository documentation is explicit that “unknown” does not mean patched. It also does not cover whether a backdoor has already been installed. The safer approach is to scan your site top to bottom with the most capable model, and, if you can afford it, keep an agent running on the server to check daily for new advisories or suspicious changes.

Two disciplines to end on: grant the agent read-only permissions at the start and require your approval before it changes anything; and never keep large numbers of API keys anywhere an attacker can reach them.

And even if you do not run a website, there is still one thing worth doing: for any API key you have stored in AI tools, revoke and regenerate it the moment you get a violation notice, and check your billing while you are at it. The OpenCode incident leaked exactly that kind of key.

11. Fixed Versions and a Self-Check Checklist

"Ten thousand urgent, please handle it tonight": days to find it, 71 days to fix it, and nobody knows how long the rollout takes

Branch Fixed version Notes
PHP 8.5.x 8.5.12 Released
PHP 8.4.x 8.4.27 Released
PHP 8.3.x 8.3.36 Released
PHP 8.2.x 8.2.35 Released
PHP 7.4.x – 8.1.x No official release Minimal source backports from the PHP security team; you must compile them
PHP 5.4.x – 7.3.x None End of life, no fixes from the PHP project — upgrade only
PHP 5.4.0 up to each branch’s fixed version — All affected; upgrading is the only complete fix

If you use distribution or LTS vendor packages, check your vendor’s advisories — they usually received the patch in advance. If you build from source, move to the versions above and then verify, machine by machine, that the workers really switched over.

Summary

Three conclusions came out of the php2shell incident for me:

  1. Upgrading is the only complete fix. Everything else is interim mitigation. PHP 8.1 and earlier have no official binary patch, and those 2.8x the installed base of unsupported servers is the real risk surface of this incident.
  2. AI changed the economics of vulnerabilities. What it compressed was not only the time spent finding bugs, but the cost of proving how dangerous they are — and once that cost collapses, the flood of vulnerabilities, the flood of reports and the imbalance in the bounty ecosystem all arrive together.
  3. Do not ask “is this AI’s fault”. The meaningful question is “is it fixed? is it rolled out?”

Similar stories will only become more common over the coming months, and harder — the tooling curve moves in one direction. If your site is still on PHP 8.1 or even 7.x, put it on today’s schedule; and if you genuinely cannot fit it in, take the site down first. Waiting is not shameful, as long as you know what you are waiting for.

Was your organization caught off guard by this one? Where is the upgrade schedule stuck? Tell me in the comments, or paste the steps you used so that whoever hits the same wall later can borrow them.

References

Further reading:
Codex Six-Month Update Roundup: 4 Token-Saving Techniques + 8 New Tricks ·
Claude Subscription Guide: Clean IPs, Self-Hosted Relays and Account Care ·
MiniMax M3.1 Flash in Practice: 7 Billion Tokens as a Workhorse Model and Agent-Powered Auto-Editing