php2shell (CVE-2026-109618, CVE-2026-109619): which PHP versions are affected and how to check yours
php2shell lets an anonymous request run code on a PHP server. Fixed in 8.5.12, 8.4.27, 8.3.36 and 8.2.35; 8.1 and older get no release. How to check your site.
On 20 October 2026 the PHP project announced an emergency security release, and on 21 October it shipped it. The two bugs it fixes, now known as php2shell, can let an anonymous visitor run their own code on a server running PHP. No login, no plugin, nothing unusual about the setup.
This one is different from the WordPress scares that come round every few months. The hole is not in a plugin or in a CMS. It is in PHP itself, the language that runs WordPress, WooCommerce, Laravel, Drupal, Magento and most of the custom-built sites in Europe. If your site is built on PHP, the question is not whether the code is affected, but whether the PHP your host runs has been patched.
In short
Update PHP to 8.5.12, 8.4.27, 8.3.36 or 8.2.35, or to your Linux distribution’s patched package, and restart every PHP process. Sites on PHP 8.1, 8.0 or 7.4 get no official release and stay exposed unless the host has built a patched package. The lasting fix for those is moving to PHP 8.3 or newer. Proof-of-concept exploit code is already public, and Cloudflare reported attack traffic against its customers on the day of the release.
What the two bugs are
The PHP security advisory of 21 October describes two separate flaws, both rated critical and both reachable without authentication:
| CVE | Name in the advisory | What goes wrong |
|---|---|---|
| CVE-2026-109618 | RCE via OOM corruption | When PHP runs out of memory mid-request, request data can be left half set up, and the cleanup afterwards treats it as valid |
| CVE-2026-109619 | RCE via stale global state | Internal state belonging to one request can outlive the memory behind it, and the next request on the same worker can use it |
Both sit in the way PHP handles a request before your application code runs. That is why they reach everything built on PHP, and why a well-written site gets no protection from being well written.
Which versions are affected
Every supported PHP branch before the fixed releases, and every unsupported one.
- PHP 8.2 to 8.5: fixed in 8.2.35, 8.3.36, 8.4.27 and 8.5.12. Anything below those numbers on its branch is exposed.
- PHP 8.6 pre-releases: fixed in 8.6.0 RC4.
- PHP 8.1, 8.0 and 7.4: affected, with no official release. The PHP project only published minimal source patches. Whether your site is safe depends on whether your host or package source built them into a new package.
- PHP 7.3 and older: affected, and on their own. Latvia’s national response team CERT.LV puts the range at every version from PHP 5 onwards.
Also worth knowing: PHP 8.2 reaches end of life on 31 December 2026. A site moved to 8.2 today will face the same question again in ten weeks.
How to check your own site
Start with a list, because the website is rarely the only PHP on a company’s servers. An online shop (WooCommerce, Magento, PrestaShop, OpenCart), a client portal, Moodle, Nextcloud, Roundcube webmail, phpMyAdmin and internal tools all count.
For each of them, the number that matters is the PHP version the web server uses, not the one a server command reports.
- WordPress: open Tools → Site Health → Info → Server. The PHP version listed there is the one running your site.
- Other PHP sites: your hosting control panel shows the PHP version per site or per domain. On cPanel it is usually under MultiPHP Manager or Select PHP Version.
- Compare the number with the fixed versions above. If you are on 8.1 or older, ask your host directly whether they ship a patched build for it. A version number alone will not tell you.
- If someone else runs the server, ask your host or developer to confirm in writing the PHP version each site runs and the date the fix was installed.
If you have your own server, php -v in a terminal is not proof. The command-line PHP is often a separate install from the one serving pages, and an updated package does nothing until PHP-FPM, Apache or LiteSpeed is restarted. PHP running in Docker needs its images rebuilt with the fixed version.
What to do
On shared or managed hosting, the host patches PHP, but you usually choose the version. If your site runs on 7.4 or 8.1 because nobody moved it, the host may have nothing to patch it with. Switch to 8.3 or newer in the control panel, and take a backup first, because old plugins and themes are exactly what breaks on a version jump.
On your own server, update PHP from wherever it came from (your distribution, a PPA such as Ondřej Surý’s, LiteSpeed’s packages, your control panel’s builds), restart every PHP process, then confirm the version through the web server, not the terminal.
If a system cannot be updated today, because it runs PHP 8.1 or older with no patched package, CERT.LV’s advice is to restrict access to it, at least from outside the country, until it can be. For an internal tool or an old admin panel, taking it off the public internet entirely is often the simpler choice.
A firewall in front of the site helps for now. Cloudflare switched on rules against php2shell for every plan, the free one included, a few hours before the disclosure. It calls them a stopgap, and attackers were already reshaping their requests to get past them. A site behind Cloudflare has more time, not a fix.
While the update is pending, the PHP project’s interim step is to set this in php.ini or the PHP-FPM pool configuration, then restart PHP:
session.upload_progress.enabled = 0
It has to be set there. ini_set() in code and .user.ini files take effect too late to help. WordPress does not use upload progress, so on a WordPress site nothing visible changes. The advisory is clear that this blocks the confirmed attack paths and not every variant: “There are no complete mitigations, updating is the only safe choice.”
One more thing: do not run anything from the “php2shell PoC” repositories appearing on GitHub. At least one ships a quick-fix script that asks for sudo. Everything needed here is a package update and one configuration line.
Signs a site was already hit
Public exploit code means an unpatched site may already have been probed. Updating PHP stops new attacks but does not remove anything already planted. Look for:
- New or changed PHP files in the web root, in
wp-content/uploads, or in/tmp - Admin users nobody recognises
- PHP processes crashing without explanation, or bursts of HTTP 500 errors around large form submissions
- The site sending spam, or the host reporting malware
If something turns up, keep the logs, change database passwords and API keys, and get someone who does clean-ups to look. That is what our hacked site recovery is for.
Why the PHP version is the part nobody owns
Most sites are not hacked by clever attackers. They are hacked through an update that nobody applied. With php2shell the update is not inside WordPress or the CMS admin, where someone might at least see a notice. It sits a level below, in the server, and on a lot of sites nobody has looked at that level since launch. We regularly find business sites still on PHP 7.4, five years after it was current, because the site worked and nobody wanted to be the one who broke it.
On 21 October we went through every server we look after and checked the PHP version each site actually runs. That check is a normal part of our maintenance plans, alongside WordPress, theme and plugin updates.
If you are not sure which PHP version your site runs, or you already know it is old and the upgrade has been put off because something might break, send us the address. We will check the version, tell you whether the site is exposed, and if it needs to move to PHP 8.3 or newer, do the move and fix what the old version was hiding.
Related: wp2shell, the WordPress core flaw from July 2026, and what actually gets WordPress sites hacked.