There is one kind of security news that is scarier than the rest: the kind where the problem isn’t in your code, or in some plugin downloaded from who knows where, but in the language itself. That’s this week.
On 21 October the PHP Security Team shipped fixes for two critical vulnerabilities in the PHP engine, CVE-2026-109618 and CVE-2026-109619, collectively nicknamed PHP2Shell. Italy’s CERT-AGID and CERT-EU issued their advisories straight away. CVSS v4.0 score: 9.2 for both.
In plain words: one crafted HTTP request, no authentication, and in some configurations the attacker runs code on the server before your application even starts.
What broke (explained without pointers)
Both flaws come from memory handling errors inside the interpreter.
- CVE-2026-109618, running out of memory halfway. If PHP runs out of memory while it is setting up a request, some internal structures are left half initialised. The cleanup code that runs right after treats them as valid. From there you get to write where you shouldn’t.
- CVE-2026-109619, state that outlives its request. A request leaves behind global state pointing to memory that has already been freed (a classic use-after-free). The next request served by the same worker trips over it. Besides code execution, PHP also confirms possible memory disclosure.
It’s like a waiter clearing a table while the customers are still ordering, then taking the wrong bill to the next table.
Who is most at risk
Practically every way of running PHP is involved: PHP-FPM, Apache with mod_php, php-cgi, FrankenPHP and LiteSpeed. According to the PHP team, though, the risk is highest with Apache mod_php, where a single unauthenticated request can trigger the exploit before any application code runs. With PHP-FPM, exploitation is only possible under specific conditions.
According to Tenable, the first vulnerable code path goes all the way back to PHP 5.4. Estimates of exposed, potentially vulnerable hosts run past a million. And researchers at Calif say they confirmed pre-authentication code execution against specific versions of WordPress, Drupal, Joomla and Magento.
In Italy, CERT-AGID specifically flags the Drupal theme italia/design-comuni-drupal-theme up to version 1.8.1 (based on Drupal 9): in other words, a good share of Italian town council websites.
Not a theoretical alarm
The timeline doesn’t leave much room for optimism:
- 17 October: Amazon Threat Intelligence sees an exploitation attempt against its honeypots, four days before public disclosure.
- 20 October: details leak ahead of the planned date.
- 21 October: the patches ship. The same day watchTowr, Cloudflare and Amazon see attacks in the wild, with payloads and infrastructure pointing to several different groups.
Public PoCs are circulating too, not all of them verified. But when attacks start before the patches, the “is it really exploitable?” debate becomes academic.
The fix: update the interpreter (not the CMS)
This is the point every advisory repeats, and it deserves bold: updating WordPress, Drupal or your plugins does nothing here. The bug is in PHP. You have to update PHP.
1. Fixed versions
| Branch | Version with the fix |
|---|---|
| PHP 8.5 | 8.5.12 |
| PHP 8.4 | 8.4.27 |
| PHP 8.3 | 8.3.36 |
| PHP 8.2 | 8.2.35 |
| PHP 7.4, 8.0, 8.1 | no official release: minimal backports from the PHP Security Team or your distribution’s packages |
| PHP 7.3 and older | no fix: time to migrate |
If you use a distribution’s packages (Debian, Ubuntu, RHEL), the version number may stay “old” because the fix arrives as a backport: check your vendor’s security advisories, not the number.
2. Find out how PHP runs on your server
# PHP loaded as an Apache module? (the worst case)
apachectl -M 2>/dev/null | grep -i php
# PHP-FPM running?
ps -eo pid,ppid,args | grep '[p]hp-fpm'
# CLI version (careful: it may differ from the web server's)
php -v
The version that matters is the one used by the web server, not the terminal. The safest way to check it is a temporary page with <?php echo PHP_VERSION;, deleted right afterwards.
3. Update and restart
On Debian/Ubuntu with system packages:
sudo apt update && sudo apt upgrade
sudo systemctl restart apache2 # if you use mod_php
sudo systemctl restart php8.3-fpm # if you use PHP-FPM (adjust the version)
The restart is not optional: as long as the old workers are alive, the vulnerable code is still in memory.
4. If you use Docker
The official php:*-apache images use mod_php. Restarting the container is not enough: the image has to be rebuilt on the new version.
docker pull php:8.3-apache
docker compose build --pull
docker compose up -d
If your Dockerfile pins an exact patch version (for example php:8.3.30-apache), bump it by hand.
5. If you’re on shared hosting
The control panel (cPanel, Plesk and the like) usually has a PHP version selector: pick a supported branch and check with your provider that the patch is already in. If your site still runs on PHP 7.x “because a plugin doesn’t work with 8”, well: it’s time to change plugin.
6. If you really can’t update right away
Stopgaps, partial ones, that do not replace the patch (the PHP team says so itself: no configuration change fully mitigates the problem):
- restrict access to internet-facing services, starting with admin panels;
- turn off
session.upload_progress.enabledinphp.iniif you don’t use it; - rate-limit requests at the web server or WAF.
Meanwhile keep an eye on the logs: unusual POST requests, Allowed memory size exhausted errors, unexpected worker crashes and restarts, child processes that shouldn’t be there.
And then there’s WordPress
You can’t talk about PHP without talking about WordPress, PHP’s most loyal customer and, at the same time, the one most reluctant to let it grow up.
Let’s recap: WordPress 7.0, released in April 2026, has finally raised the minimum requirement to PHP 7.4. A version that stopped receiving security updates in November 2022. To put it in perspective, it’s like a garage proudly announcing that from this year on it no longer accepts cars without brakes, as long as they at least have drum brakes.
The result is an ecosystem where “it still works” beats “it’s still supported”, where the slider plugin bought in 2017 decides the PHP version of the whole server, and where WordPress automatic updates give many people the reassuring feeling of being safe. Automatic updates that, by the way, don’t touch the PHP interpreter at all.
PHP2Shell is not WordPress’s fault, to be clear. But if a few million sites now have to rush to update a PHP that has been sitting still for years, part of the responsibility lies with a CMS that spent a decade telling its users that was fine.
In short
- Two critical flaws in the PHP engine, CVSS 9.2, unauthenticated remote code execution.
- Exploited in the wild even before the patches.
- Highest risk with Apache mod_php, including the
php:*-apacheDocker images. - There’s only one fix: PHP 8.2.35, 8.3.36, 8.4.27 or 8.5.12, then restart the services and check the version actually in use.
- Updating the CMS isn’t enough. Staying on PHP 7.x today is a choice, not bad luck.
Sources: CERT-AGID, PHP announcement, CERT-EU, Tenable, watchTowr, WordPress: dropping support for PHP 7.2 and 7.3.
