On October 21, 2026, PHP shipped emergency security releases 8.5.12, 8.4.27, 8.3.36 and 8.2.35. They fix two flaws that picked up the name PHP2Shell: CVE-2026-109618 and CVE-2026-109619. Both carry a CVSS score of 9.2, and both let an unauthenticated attacker run their own code on your server.
One thing makes this different from the usual plugin vulnerability. There is nothing to uninstall. The problem is in the language your site runs on, whether that site is WordPress, Laravel or something custom.
What actually broke
While handling a request, PHP keeps an eye on how much memory it has. When it runs out, it abandons the work in progress by jumping elsewhere in the code (the longjmp function) and starts cleaning up. The trouble is that at that moment some of the data is only half prepared. Cleanup then reads leftover bytes where a valid value should be. An attacker who can trigger memory exhaustion on demand can influence what those bytes are.
The second flaw is from the same family. After a fatal error, a chunk of old state is left behind in the worker process that serves requests. The next visitor hits a server that remembers someone else's request and reaches into memory it already freed.
Either way the result is the same: a web shell. A script that lets an attacker drive your server as if sitting in front of it.
Who this affects
Practically anyone running a PHP site on an unpatched version. Everything before 8.2.35, 8.3.36, 8.4.27 and 8.5.12 is vulnerable. The way you run it makes no difference: Apache with mod_php, PHP-FPM, php-cgi, LiteSpeed and FrankenPHP are all affected, in default configuration. You do not need anything unusual turned on.
If you are still on 7.4, 8.0 or 8.1, those branches are out of official support, but backports of the fix exist. Treat it as a good reason to plan the upgrade, because next time you may not be this lucky.
For a sense of scale: Palo Alto's Cortex Xpanse counted over 22 million publicly reachable PHP instances that could be vulnerable. That is not a count of compromised sites, it is a count of doors someone could try knocking on. On October 26, CISA added both flaws to its catalogue of actively exploited vulnerabilities.
One correction worth making, because the first days after news like this are full of noise. Unit 42 initially described an intrusion at a European government agency as possibly resulting from PHP2Shell, then retracted that on October 25 because it could not confirm the link. It changes nothing about how urgent the update is.
What we did for our clients
The sites we look after run on managed hosting, where PHP is updated centrally. That is convenient, but taking the provider's status page at its word did not feel like enough. We went project by project, checked the version the server actually reports (not the one the admin panel claims) and read through the logs from the days around October 21. We found nothing suspicious.
Clients on a monthly maintenance plan mostly never heard about any of it, because this is what that plan is. We emailed the rest.
How to check for yourself
Five minutes, no more.
- In your hosting admin (cPanel, Plesk or a custom panel), find the PHP version setting. You need the full number. "PHP 8.3" is not enough; the gap between 8.3.35 and 8.3.36 is exactly what this article is about.
- In WordPress, the same number is under Tools → Site Health → Info → Server.
- Send your host one question: which PHP version is my site on, and when did you deploy the fix for CVE-2026-109618? An answer along the lines of "you're protected" without a version number is not enough, in our view.
Then came a third flaw, two days later
On October 23, PHP disclosed another path to code execution, CVE-2026-115560. There is no patch yet; it will land in a regular bugfix release. Exploiting it takes an unusual combination of settings: session.serialize_handler has to be set to php_binary or php_serialize, the application has to switch it to php at runtime via ini_set() before session_start(), and session.upload_progress.enabled has to be on. The PHP team considers that combination close to nonexistent in real deployments.
The recommended protection is to turn upload progress tracking off, so session.upload_progress.enabled=0 in php.ini or the FPM pool config. Anyone who left it off after October 21 already has this path closed.
If you cannot update right away
Only the patch fixes this. Datadog says so bluntly in its write-up and we agree: you cannot configure your way out of it. While you wait on your host, it makes sense to limit outside access to the application and watch for these traces:
- memory exhaustion errors with an odd "Unknown on line 0" in the log
- unusually large form submissions carrying
PHPSESSIDorPHP_SESSION_UPLOAD_PROGRESSfields, or hundreds of form parts inside one small request - crashing workers and segmentation faults in the server log
- a shell process spawned by a web process, the most reliable sign on this list
If you do find something, don't delete it blindly. Call your developer or host, and plan on restoring from a clean backup and rotating passwords.
Not sure whether your site is in the clear? We can go through it as part of a security audit.