Skip to content
PROTECT MY WP

This Week's Critical Bug Was in PHP, Not WordPress

By 8 min read

On 21 October 2026 the PHP project released 8.5.12, 8.4.27, 8.3.36 and 8.2.35 to fix two vulnerabilities, CVE-2026-109618 and CVE-2026-109619, both rated 9.2 out of 10. Either one lets an unauthenticated request execute code on the server. The details leaked on 20 October, two days before the planned disclosure, the release was brought forward, and watchTowr's honeypots saw exploitation attempts the same day the fix shipped. The pair has picked up the name PHP2Shell.

It is not a WordPress bug or a plugin bug, so there is no WordPress update that fixes it and no plugin that closes it. If your security routine is keeping plugins current, this one went straight past it.


What broke

Both bugs live in how PHP handles the lifecycle of a request, below anything your application does.

The first, CVE-2026-109618, is in out-of-memory handling. When PHP runs out of memory it bails out of whatever it was doing with a long jump. If that happens while the request's internal data is only partly set up, the cleanup code that runs afterwards trusts data that was never finished, and an attacker who can control the layout of the request can turn that into code execution. A large or oddly shaped multipart request is one way to push a worker into that state on demand.

The second, CVE-2026-109619, is stale state. PHP keeps some global pointers to memory that belongs to a request. If those are not reset before the memory is freed, the next request handled by the same worker process can use them before normal initialisation runs. The confirmed paths are the session upload progress feature and, on PHP 8.5, fatal error backtraces. The advisory is careful to say those are the confirmed paths, not the only ones.

Every way of serving PHP over the web is affected: PHP-FPM, Apache with mod_php, php-cgi, FrankenPHP and LiteSpeed. The PHP team rates mod_php the highest risk, with a demonstrated exploit where the attack succeeds before any application code has run. FPM is not safe, but a pool of short-lived workers with sensible limits is a harder target than a long-lived Apache process with the interpreter inside it. If you are still on mod_php, this week is the argument for moving.


Who patches it

On managed WordPress hosting, your host does. The good ones had the patched packages out within hours, because distributions were given the fix ahead of the announcement. cPanel and CloudLinux shipped updated EasyApache packages promptly. Cloudflare had firewall rules for the known exploit shapes live on every plan, including free, from 03:02 UTC on the 21st, about nine hours before the release, which buys time but is not a fix, because the advisory itself says no configuration change fully mitigates these. If your host has said nothing, ask. The question is specific: which PHP build is my site running, and does it contain the fix for CVE-2026-109618?

On a VPS, you do, and there is a catch. On Ubuntu and Debian the fix arrives as a backport into the distribution's existing package, so the version string does not change to 8.3.36. A patched Ubuntu 24.04 box still reports 8.3.6. The way to check is the package changelog or the distribution's security advisory, not php -v:

apt changelog php8.3-fpm | head -40

Then update and restart the workers. A patched binary on disk does nothing for the processes already running:

sudo apt update && sudo apt upgrade
sudo systemctl restart php8.3-fpm

Substitute your version. If you run multiple PHP versions from a third-party repository such as Ondřej Surý's, each one needs its own package and its own restart. If you have a PHP binary installed from source, or one that shipped with a control panel that bundles its own, it will not be touched by the system package manager at all, and that is the install most likely to still be vulnerable in a month's time.


The unsupported versions

The fixes exist for 8.2 and later. PHP 8.1 and older no longer receive releases from the project. Because of the severity, the security team published minimal source backports for 7.4, 8.0 and 8.1, which is unusual and helps distributions and people who build from source. It does nothing for a shared host that simply left 8.1 selected in a control panel. PHP 7.3 and older have no fix at all.

Last month's post on the 20i dataset found that a large share of sites are still on PHP versions the project stopped supporting years ago. For those sites there was no patch this week. The only fix is to move to a supported version, which is the move they have been putting off. PHP 8.2 leaves security support at the end of this year, so a site that reaches 8.2 today has about ten weeks before it is back in the same position.

If a site cannot move yet, there is a paid stopgap. Freexian maintains security-patched Debian and Ubuntu packages for end-of-life PHP branches, back to 5.6, delivered through an APT repository. I dealt with them this week for exactly this reason and the experience was good. It buys time on a server you cannot upgrade this month. It is not a reason to leave it there.


The settings worth changing anyway

The PHP advisory lists configuration changes that reduce exposure to the specific paths that were demonstrated, and says plainly that none of them makes an installation safe. They are still worth doing. Some are good practice on any server, and the variants they do not cover are harder to exploit than the ones they do.

  • Lower post_max_size. The advisory suggests 8M for applications that take no file uploads and 32M where they do, with upload_max_filesize kept below it. Earlier editions of the handbook suggested 64M as a starting point; Chapter 1 now says 32M. That is enough for almost every WordPress site, since media over that size should be going through SFTP anyway, and the smaller the request a worker will accept, the less an attacker can do with the memory path.
  • Set session.upload_progress.enabled = 0 in php.ini or the FPM pool, then restart. Not in .user.ini and not with ini_set(), because the vulnerable path runs before either applies. WordPress does not use session upload progress.
  • On PHP 8.5, set fatal_error_backtraces = 0 and restart. Same reasoning.
  • Enforce request limits at nginx or Apache as well. Body size, header count, multipart part count. client_max_body_size in nginx is the obvious one, and it should match the PHP limit rather than sit well above it.
  • Fix fatal errors you can reach from outside. A plugin that throws on a crafted input is now a potential entry point for the second bug, not just an error log line.

One item in the advisory cuts against the usual advice. It suggests removing the PHP memory limit entirely, with memory_limit = -1 set at the pool level so applications cannot override it, so that the controllable out-of-memory failure cannot be triggered. That trades a code execution path for a resource exhaustion one, and the advisory pairs it with a container or cgroup limit as the availability boundary. If you do that, make sure the cgroup limit exists first. Without it you have removed the one thing stopping a single request from eating the box.


Why this one matters more than the plugin bugs

A plugin vulnerability has a shape you can reason about. It needs the plugin installed, usually a particular feature enabled, often a particular endpoint reachable. You can put a rule in front of it. The Elementor Pro flaw in August was a 9.8, and a single server rule blocking PHP in uploads made it a dead file.

PHP2Shell has no such shape. Every PHP site on the internet was a target on 21 October, regardless of what it ran, and the bug sits below the layer where WordPress or a security plugin could see it. A fully updated WordPress install with every plugin current, a firewall plugin, two-factor on every account and PHP execution blocked in uploads was still open, because none of that runs until after the vulnerable code has already handled the request.

The layer that fixes it is the one most WordPress owners never think about and most "security plugins" cannot touch. It is also the layer where managed hosting is either earning its money or not. If your host patched PHP on 21 October without you asking, that is what you are paying for. If you are finding out from a blog post, that tells you something about your host.


Where this fits

Chapter 1 of the Protect My WP handbook covers the server and hosting environment: PHP support windows as fixed dates, FPM over mod_php, the php.ini settings worth changing and why, including the ones above, and what to ask a host before you trust it. It was updated this week with this advisory as the worked example. Chapter 1 also covers unattended security upgrades on the server itself, which is the thing that would have patched this for you overnight, and Chapter 12's review checklist makes sure they are still on.

Get the book for £19.

More on this topic

Want to go deeper?

Protect My WP is the whole handbook: 14 chapters from the server up, kept current as WordPress changes, with a PDF edition included. £19, one payment, every future update. Not sure yet? The foreword and Chapter 1 are free, and the shorter guide walks the same ground faster.