PHP maintainers announced on October 20 that they’d ship emergency patches the next day for two critical bugs, CVE-2026-109618 and CVE-2026-109619. Within 24 hours, government sites across Europe were going dark as a precaution. By the time the dust settled, this was being called the worst PHP incident since Heartbleed, and the detail everyone’s stuck on is that a human researcher didn’t find it. An AI did.
Part of why this got so messy is that PHP doesn’t just run “websites” in the obvious sense. It’s underneath WordPress, Drupal, Joomla, and Magento, sure, but it’s also baked into shared hosting panels, admin control panels, and a long tail of software that never advertises it’s running PHP at all. When a bug lives in PHP core itself instead of a specific application, there’s no clean list of “who’s affected.” Everyone running PHP for any reason is affected, and most of them don’t know it yet.
Key takeaways
- Two critical, unauthenticated RCE bugs in PHP core (CVE-2026-109618, CVE-2026-109619), CVSS 9.2 each.
- Found by AI-assisted research (Calif, Wiz) in August, patched early on October 21 after details leaked on Hacker News.
- Fixed in PHP 8.5.12, 8.4.27, 8.3.36, 8.2.35. PHP 7.4, 8.0, and 8.1 only got minimal unofficial backports; anything older is unsupported.
- mod_php installs are highest risk: the bug can trigger before any of your own application code even runs.
- If you can’t patch immediately, take the server offline or disable
session.upload_progressas a partial, not complete, mitigation.
The bugs themselves
Both CVEs are the same basic class of problem: stale internal state surviving where it shouldn’t. Per NCSC’s writeup:
- CVE-2026-109618: an out-of-memory condition can interrupt PHP mid-request while internal request data is only partially initialized. Cleanup code then treats that half-built data as if it were valid.
- CVE-2026-109619: a worker process can keep using request-owned internal state after its backing memory has already been freed. The next request handled by that same worker can end up touching the stale, freed state before normal initialization resets it.
Both are rated 9.2 on CVSS v4.0 and both allow unauthenticated remote code execution. No login, no credentials, just a crafted request. Fixed in PHP 8.5.12, 8.4.27, 8.3.36, and 8.2.35. PHP versions from 5 through 8 are considered potentially affected, so “we’re on a newer version” isn’t automatically a pass. Every deployment mode that serves web requests is in scope: PHP-FPM, mod_php, php-cgi, FrankenPHP, LiteSpeed. mod_php is specifically called out as highest risk, since PHP confirmed the bug can trigger before any of your own application code runs at all. PHP says it validated full RCE over plain HTTP against a default mod_php setup and a standard multi-worker prefork configuration, not a contrived lab setup.
How these are actually exploited
Both NCSC and PHP’s own advisory describe the trigger mechanism in detail, but deliberately stop short of explaining how the corrupted memory state actually turns into running code. That step is being withheld while patch adoption catches up. Here’s the confirmed part of each chain:

CVE-2026-109619 is a different bug with the same outcome. Instead of an out-of-memory interrupt, it’s stale state surviving across two separate requests handled by the same worker:

Security firm Calif’s PoC tool, which it’s calling PHP2Shell, reportedly chains both bugs together into a single no-login attack, and says it reproduced working code execution against unpatched Magento, WordPress, Drupal, Joomla, MediaWiki, Roundcube, phpMyAdmin, Nextcloud, Laravel, Symfony, and WHMCS installs. watchTowr separately confirmed it reproduced CVE-2026-109618 specifically. Neither has published the exact payload. Unverified “PoC” exploit code is already circulating on GitHub, and Tenable’s advisory specifically warns that this code is unverified, with some of it found laced with malware. Treat anything claiming to be a working exploit as untrusted until a major vendor confirms it.
How it actually came out
The timeline matters here more than usual. Security firm Calif says it found the bugs back on August 1, using an LLM-assisted research process. Wiz separately found them using its own autonomous tool, Wiz Atlas, paired with Google’s Gemini 4 Argon and OpenAI’s GPT-5.6 Sol. That’s roughly two and a half months of quiet, coordinated work with the PHP core team before anything went public, the normal, responsible way this is supposed to go.
It didn’t stay quiet. A post on Hacker News on October 20 claimed the vulnerabilities were being disclosed early; it got taken down, but not before screenshots of it spread. watchTowr independently confirmed the leaked info was real, with one researcher noting bluntly that “we were all supposed to wait until Thursday at 11am ET.” PHP’s own security team had already reserved the right to release early if details leaked or exploitation showed up, and that’s exactly what happened: the release moved up to Wednesday, October 21 at 14:00 UTC, a full day ahead of the original plan. Amazon’s security team says it caught an exploitation attempt against one of its honeypots on October 17, four days before the public disclosure, from what looked like a real threat actor rather than researcher traffic. Nobody’s fully explained yet how that happened before the leak went wide.
Who actually went dark
This wasn’t abstract. Real, named infrastructure got pulled offline as a precaution:
- In the Netherlands: the Port of Rotterdam, the government portal Overheid.nl, the KNVB (the Dutch football association), several major political parties’ sites, and hospital websites.
- Finland’s Valtori took government network services offline.
- France’s Interior Ministry put its sites into preventive maintenance.
- Wikipedia‘s operator pulled down some systems, and the Internet Archive briefly went offline too.
It reached head-of-state level: the Dutch PM said he was personally monitoring it, and Japan’s PM Sanae Takaichi told website owners directly to go check whether they’re running PHP.
Why this is bigger than one patch Tuesday
PHP runs something like 70 to 75% of the web, depending on whose count you use (W3Techs says 75% of sites where the language is identifiable). It’s the engine under WordPress, Drupal, Joomla, and Magento, basically anything you’d call “a normal website.” That’s why Censys counted 2.58 million PHP hosts exposed to the internet, with roughly 1.575 million of them still running a version old enough to be vulnerable.
But the number that’s actually getting talked about in security circles isn’t the exposure count. It’s that this bug sat in PHP’s codebase, public and readable, for over a decade, and nobody caught it by hand. Calif and Wiz both say this specific flaw would’ve been genuinely hard for a human to find through normal code review. An AI model found it anyway. Everyone calling this “the Heartbleed of the PHP era” isn’t just talking about the blast radius, they’re talking about what it means that this is now how critical bugs in decade-old, heavily reviewed code get found.
Detection guidance
This is the part most coverage skipped: what should actually be in your detection rules right now, independent of whether you’ve patched yet. Huntress’s SOC, which is actively watching partner systems for this, published concrete guidance rather than just “patch now”:
- Alert on web server processes spawning shells or tools they shouldn’t.
php-fpm,php-cgi,httpd, orapache2launching a shell interpreter, or reaching forcurl,wget,nc, orcertutil.exe. - Watch for raw socket / reverse-shell patterns in command lines: things like
/dev/tcp/,fsockopen, ormkfifoshowing up in a web server’s child process. - Flag basic recon commands running from a web server context:
whoami,id,uname -a,ipconfig. None of those have any business running as a child of your PHP worker. - If you don’t have EDR on a Linux box, Florian Roth’s free process-watcher tool run in observe mode is a reasonable stopgap until you do.
Huntress’s own expectation, echoed from Florian Roth, is that real-world exploitation will most likely show up as exactly this kind of odd child process coming out of a PHP worker, since that’s what it sees in the large majority of PHP intrusions already, php2shell-related or not. As an example of what that actually looks like, Huntress recently caught a PHP FastCGI process, unrelated to this incident, repeatedly running a one-liner that wrote a small PHP file containing a random marker string into the first writable temp directory it could find, executed it, then deleted it again, printing a flag string only if no directory was writable. That’s the general shape of the behavior to hunt for: PHP spawning something it has no business spawning.
The risk isn’t evenly distributed either. Huntress specifically flags exposed Linux web servers and shared hosting as the places this is likeliest to be exploited quietly and go completely unnoticed, since those boxes are often the least monitored part of a company’s whole environment.
If you find something: isolate the box, preserve the web server and PHP logs before you do anything else, then check the web root for new or modified files (webshells), and check for new cron jobs, scheduled tasks, or accounts you didn’t create.
Worth noting on the credential-exposure angle specifically: Wiz didn’t just demonstrate RCE against WordPress, Drupal, and Joomla. It separately found a related memory-disclosure path that can leak passwords, tokens, API keys, and certificates sitting in server memory, independent of whether full code execution succeeds. That’s a second reason to treat “we patched” as the finish line, not “nothing happened yet.”
As of the afternoon of October 21, Huntress said it hadn’t observed active exploitation against its own partner base yet, even as other researchers reported seeing attacks elsewhere. “No detections yet” isn’t the same as “not affected,” especially this early.
What to actually do
If you run WordPress, Drupal, Joomla, or Magento, you run PHP, full stop. CISA, NCSC, and the NSA are all saying the same thing: patch now, and if you genuinely can’t patch right now, take the system offline rather than leave it reachable. Cloudflare’s updated WAF rules are a stopgap to buy time, not a substitute for the actual patch.
Sourced from NCSC’s advisory, Ars Technica, Reuters (via CNBC/multiple syndication), The Conversation, Help Net Security, Global Banking & Finance, and Huntress’s own incident-response writeup. Technical CVE descriptions are NCSC’s own wording; attribution for the AI-assisted discovery (Calif, Wiz Atlas, Gemini 4 Argon, GPT-5.6 Sol) reflects those outlets’ reporting.
Sources:
- Critical security issue affecting PHP: NCSC
- Government websites go dark as software flaw sparks security scramble: CNBC/Reuters
- Critical web security flaws spark global alarm as Google, OpenAI and Amazon respond: CNBC
- PHP2Shell: Critical PHP vulnerabilities patched, update now!: Help Net Security
- PHP warns admins of two critical flaws, emergency patches coming tomorrow: BleepingComputer
- A critical flaw affecting 70% of all websites has the cybersecurity world panicked: The Conversation
- AI-Discovered PHP Vulnerability Forces Government Sites Offline: Global Banking & Finance
- Explainer: What Is PHP and Why Did It Take Government Websites Offline?: U.S. News
- PHP2Shell: Leaked Critical PHP Vulnerabilities: Huntress








Leave a Reply