On 21 October 2026, the PHP team shipped urgent releases 8.5.12, 8.4.27, 8.3.36 and 8.2.35. They fix two critical vulnerabilities rated 9.2 on CVSS v4.0 that allow unauthenticated remote code execution. The press has dubbed the pair PHP2Shell. The official guidance is blunt: update immediately, because there is no complete workaround.

What makes it worse: an exploitation attempt was recorded on 17 October – four days before public disclosure. The UK’s NCSC advises considering taking offline any system that can’t be patched right away. If your site runs on PHP – and that includes most sites built on WordPress, Laravel and other popular platforms – this article is about you.

What was found

CVE-2026-109618: code execution via memory corruption on out-of-memory

When PHP runs out of its memory limit, it aborts the request abruptly. The problem is that this can happen while the request’s internal data is only partially initialized – and the cleanup code then treats that data as valid. An attacker can deliberately trigger the out-of-memory condition with a crafted multipart request (the same format used to submit forms with files): a huge number of headers in a single part, empty file fields, deeply nested field names.

For Apache with mod_php, full code execution over HTTP has been confirmed with default settings. For PHP-FPM, source analysis shows it is susceptible, although no complete working exploit has been demonstrated.

CVE-2026-109619: stale state between requests

A PHP worker process handles one request after another. The second vulnerability is that some internal state can outlive its request and keep pointing at memory that has already been freed. If the next request landing in the same worker touches that state before it is reset, you get a use-after-free that can be escalated to code execution.

One of the confirmed paths is session upload progress, the mechanism that tracks file upload progress. It is enabled by default and works even if the application never calls session_start(). This path has been confirmed against both mod_php and PHP-FPM.

Who is affected

According to the official announcement, every PHP installation that serves web requests is at risk: PHP-FPM, Apache with mod_php, php-cgi, FrankenPHP, LiteSpeed. The risk is highest with mod_php.

Crucially, the attack fires before your site’s own code runs. So it doesn’t matter how carefully your theme, plugins or application are written – only the PHP version matters.

  • PHP 8.2–8.5 – update to 8.2.35, 8.3.36, 8.4.27 or 8.5.12 respectively.
  • PHP 8.1 and older – there will be no official releases. The PHP team published minimal source patches for 7.4, 8.0 and 8.1 for people who build PHP themselves, and some distributions and extended-support vendors ship their own fixes. But the right answer is moving to a supported version.

How to fix it, step by step

1. Find out which version actually serves your site

php -v shows the command-line version, and your site may be running on a different one. Check FPM specifically, and every installed version:

php -v
php-fpm8.4 -v
ls /etc/php/
systemctl list-units 'php*-fpm*'

During a recent audit we found a spare PHP 8.3 on a server: nothing used it, but its processes were running. An unused version is the same vulnerability with none of the benefit – remove it.

2. Update the packages

On Ubuntu/Debian with Ondřej Surý’s repository:

sudo apt update
sudo apt install --only-upgrade 'php8.4-*'

If PHP comes from your distribution’s own repositories, install its security updates. The version number may stay “old”, because distributions backport fixes into their own packages. Check the package changelog; if it doesn’t mention the CVE IDs, confirm the status with your vendor – some of them don’t list CVEs in changelogs.

In Docker, restarting the container is not enough: rebuild the image on a fresh version (for example php:8.4.27-fpm) and redeploy. On shared hosting, check the PHP version in your control panel or contact support.

3. Restart the PHP processes

Worker processes started before the update keep the old code in memory. After installing the packages, always restart the services:

sudo systemctl restart php8.4-fpm
# or, for Apache with mod_php
sudo systemctl restart apache2

4. Verify

php-fpm8.4 -v
systemctl show -p ActiveEnterTimestamp php8.4-fpm

The version should be the fixed one, and the service start time should be later than the update.

If you can’t update right now

The official advisories are explicit: none of the interim measures make an installation safe. They only reduce the risk until you update:

  • Disable session upload progress: session.upload_progress.enabled=0, then restart the workers. If you don’t use the feature, the advisory recommends keeping it disabled even after updating.
  • Block multipart requests wherever your application doesn’t accept file forms, and cap request size at the web server.
  • On PHP 8.5 – set fatal_error_backtraces=0.
  • WAF: Cloudflare has deployed rules for the known attack vectors, including on the free plan.

Why “PHP 7.4 still works” is no longer an argument

This incident shows exactly where running an unsupported version leads. Only branches with security support get fixes:

Version Security support until Status
PHP 7.4 28 Nov 2022 end of life
PHP 8.0 26 Nov 2023 end of life
PHP 8.1 31 Dec 2025 end of life
PHP 8.2 31 Dec 2026 security only, ends in two months
PHP 8.3 31 Dec 2027 security only
PHP 8.4 31 Dec 2028 active support
PHP 8.5 31 Dec 2029 active support

This time, source patches were published for the old branches – but that’s the exception, not the rule, and building PHP with a patch yourself is not something everyone can do. Next time there may be no such courtesy.

The second problem is outdated servers. On Ubuntu 18.04, for example, PHP 8 can no longer be installed from the standard repositories, so moving to a new PHP version means moving to a new server. That was exactly our case – we covered how to do it without downtime in a separate article: Moving a Website to a New Server with Zero Downtime.

If you’re planning the upgrade, here is a short plan:

  1. Update WordPress, your theme and plugins first – most compatibility work has already been done there.
  2. Check your own code: php -l of the target version, and for a deeper check, the PHPCompatibility ruleset for PHP_CodeSniffer.
  3. Deploy a copy of the site on the new PHP version and walk through the key flows: forms, payments, the admin area.
  4. Switch the live site only once the copy runs with clean error logs.
  5. Target PHP 8.4: it gets security support until the end of 2028.

Need help upgrading PHP?

I’ll check which PHP version is actually running on your servers, update it without downtime, test your theme and plugins for PHP 8 compatibility – and if your current server can’t run a modern version anymore, move your site to a new one.

Discuss your upgrade

Sources