PHP2Shell Hit Every PHP Since 5.4, and Exploit Attempts Started Four Days Before the Patch. Here's the 30-Minute Check for Your Servers.
PHP shipped emergency patches on October 21 for two remote code execution bugs, tracked as CVE-2026-109618 and CVE-2026-109619, both scored 9.2 on CVSS v4.0 and both exploitable without logging in. Amazon's honeypot network recorded an exploitation attempt on October 17, four days before anyone could install a fix. If you run WordPress, Laravel or any PHP app for yourself or for clients, the patch you need is not in your app. It is in the runtime underneath it.
What actually broke
These are bugs in PHP itself, not in a plugin or a framework. According to The Hacker News, nearly every version back to PHP 5.4 is affected, across PHP-FPM, Apache mod_php, php-cgi, FrankenPHP and LiteSpeed. The first bug involves PHP running out of memory halfway through setting up a request and leaving internal data half-built. The second lets state outlive the memory it points to, so the next request handled by the same worker can act on leftovers.
The risk is not equal across setups. Mod_php is the worst case: watchTowr describes an attack that can succeed before any application code runs. PHP-FPM is murkier. PHP's own advisory says FPM is susceptible, but a complete FPM exploit had not been shown for one of the two bugs. I would not read that as safe. Memory disclosure alone can leak passwords, tokens and API keys from other requests on the same worker.
The timeline is the scary part
Details leaked on October 20, before the coordinated release, and a proof-of-concept video went up by mistake the same evening. PHP moved the release from October 22 to October 21. Help Net Security reports that Amazon Threat Intelligence saw its first attempt on October 17, from an address tied to a commercial anonymization service, and nobody knows how the attacker got details early. Then watchTowr's honeypots saw active exploitation attempts against both CVEs on October 21.
Nobody has confirmed a successful break-in at a specific server as of the sources I read. That will change the way these things usually change: slowly, then in a batch of postmortems. BambooHR took its service offline in several regions as a precaution, and several Dutch government sites went dark. When organizations that size pull the plug rather than wait, a two-person agency should take the hint.
The version table you need
The fixed releases are 8.5.12, 8.4.27, 8.3.36 and 8.2.35. PHP 8.1 and older no longer get official updates. The PHP security team published minimal source backports for 7.4, 8.0 and 8.1, and distributions that maintain long-term packages should have their own fixes under older-looking version numbers, so check the package changelog for the CVE IDs rather than trusting the number. PHP 8.2 reaches end of life on December 31, 2026, which makes this a good week to schedule that migration too.
If you are on 7.3 or older, there is no fix. You need to move.
The 30-minute check
Here is the order I would run it in.
First, find out which PHP is actually serving requests. The CLI binary on a server is often a different version from what Apache or FPM is running. Put a one-line phpinfo() behind a password, or check the service's package version, and write it down for every site.
Second, update the runtime from the server package, host panel or container image, then restart Apache, PHP-FPM and any long-running workers. Skipping the restart is the classic mistake. The patched files can be on disk while the vulnerable process keeps running.
Third, apply the stopgaps only where you cannot patch yet. For the memory bug, PHP suggests setting memory_limit=-1 so applications cannot override it, keeping post_max_size low and enforcing request-size limits at the web server or proxy. For the second bug, set session.upload_progress.enabled=0 and restart workers. PHP is explicit that only updating fully protects a server, and watchTowr goes further and says ini-based mitigations are ineffective, so treat these as a bandage.
Fourth, if you sit behind Cloudflare, check that the managed rules are on. Cloudflare switched on WAF rules for the known vectors for all customers, free plans included, but attackers were already changing payloads to get around them. A firewall rule buys you hours, not safety.
Fifth, look for damage. Unusual large or deeply nested multipart requests followed by memory-limit errors or repeated HTTP 500s, oversized PHPSESSID cookies, unexplained worker restarts, new files in web roots and outbound connections from PHP processes you cannot explain are all worth a look. Preserve logs before you change anything.
Where this could be less bad than it sounds
I have a real counter-argument against panic. Only one of the two bugs has a demonstrated exploit that works against FPM, and that path depends on an operation in the running application. If your sites sit on managed hosting with a competent provider, the provider has probably already patched. A shared host that updated on October 21 has done more for you than you could have done yourself.
The other caveat: part of the severity story is still moving. A leaked claim of a 10.0 score did not come from PHP, whose own rating is 9.2, and some vendors, including Palo Alto Networks for PAN-OS, were still waiting on fixes as of October 22. Expect corrections.
What I'd actually do
I would treat this as a same-day job for any server I am responsible for, and I would do it in this order: client sites on mod_php first, then FPM boxes, then my own side projects. If you resell hosting or maintain WordPress for a handful of clients, send them one short message that says what happened, which PHP version you moved them to and when. Clients forgive a patch. They do not forgive finding out from the news that you did not mention it.
Then write the PHP version of every site you host into a single file. This week showed that the layer you do not think about is the one that bites, and a one-page inventory turns the next emergency from a scavenger hunt into a five-minute loop.
Author
Lukas
@lukcombinator