Skip to content
IT Infrastructure

PHP2Shell: Updating WordPress Won't Patch It. Here's How to Patch the PHP Underneath

CVE-2026-109618 and CVE-2026-109619 are in PHP itself, so a WordPress update does nothing and a running container keeps its old PHP. How to check the version that really serves requests, rebuild, mitigate and look for signs of compromise.

H
Hamze Zare Nasiri
October 26, 2026
PHP2Shell: Updating WordPress Won't Patch It. Here's How to Patch the PHP Underneath

On 21 October 2026 the PHP project released 8.5.12, 8.4.27, 8.3.36 and 8.2.35 and told every PHP user to update immediately. The two bugs they fix, CVE-2026-109618 and CVE-2026-109619, now known as PHP2Shell, can let an attacker run code on a web server without logging in. The researchers behind the disclosure demonstrated it against WordPress, Drupal and Joomla.

The part that catches people out is where the bug lives. It is in PHP itself, not in WordPress or a plugin. Clicking "Update" in the WordPress dashboard does nothing for it, and neither does updating Composer packages. If your site runs in Docker, a running container keeps the PHP it was built with until you rebuild it. This guide covers how to check what you actually run, how to patch it, and what to look at afterwards.

What PHP2Shell is

According to the PHP project's security advisory, the two flaws are:

  • CVE-2026-109618, RCE via out-of-memory corruption. When PHP runs out of memory at the wrong moment, it can leave request data half-initialised, and the cleanup code later treats that data as valid.
  • CVE-2026-109619, RCE via stale global state. State that belonged to one request can survive after its memory is freed, and a later request handled by the same worker can use it.

The disclosure site, from Wiz Research, OpenAI Codex Security and Calif, rates both at CVSS 9.2. It reports pre-authentication remote code execution on WordPress, Drupal and Joomla, and says the second bug can also leak worker memory. Its point that matters most for site owners: a plain "Hello World" script on an affected PHP version is exposed too, because the vulnerable code runs before your application does.

The PHP project lists PHP-FPM, Apache with mod_php, php-cgi, FrankenPHP and LiteSpeed as affected, and considers the risk highest for mod_php, where it has a working exploit that fires before any application code runs. Red Hat's bulletin adds that its default PHP-FPM setup makes exploitation harder in practice, and that mod_php with default configuration is at higher risk. That distinction matters for WordPress in Docker: the official wordpress:*-apache images run PHP inside Apache as mod_php.

Step 1: check the PHP that is actually serving requests

On a plain server, php -v tells you the CLI version, which is not always what the web server uses. On Debian and Ubuntu it can also mislead you in the other direction: Ubuntu fixed PHP2Shell by backporting the patch, so Ubuntu 24.04 is safe on 8.3.6-0ubuntu0.24.04.13 even though the version still says 8.3.6. Compare the full package version with your distribution's advisory, not the upstream number.

For containers, ask each running container directly. This lists every container on a host that has PHP in it, with its version and image:

for c in $(docker ps --format '{{.Names}}'); do v=$(docker exec "$c" php -r 'echo PHP_VERSION;' 2>/dev/null) && echo "$c $v $(docker inspect -f '{{.Config.Image}}' "$c")"; done

Official PHP builds are fixed from 8.2.35, 8.3.36, 8.4.27 and 8.5.12. Anything below that on the same branch, or anything on 8.1 or older, needs action.

Step 2: rebuild, do not just restart

Docker says its Official Images on Docker Hub already carry the fixed PHP. That only helps once you pull them. A restart reuses the old image, and a Dockerfile that pins an exact patch tag, such as FROM php:8.2.33-apache, will never pick up the fix on its own. For a Compose project built from a Dockerfile:

docker compose build --pull && docker compose up -d

For a service that uses a published image directly, run docker compose pull before up -d. Then run the loop from step 1 again and confirm the new version inside the container. If a third-party image (a ready-made LAMP stack, a vendor appliance) has not shipped a fixed release yet, you are waiting on that vendor, and the mitigations below are all you have.

Step 3: if you are on PHP 8.1 or older

PHP 8.1 and earlier no longer get releases from the PHP project. The security team did publish minimal source backports for 7.4, 8.0 and 8.1 for people who build from source, and some distributions and LTS vendors ship their own fixed builds. A container built from an old php:7.4 tag gets neither. Older WordPress sites that depend on ionCube-encoded plugins often sit on 7.4 for exactly that reason. The real fix is to move them to a supported branch. Until then, treat them as exposed.

Mitigations while you patch

Both the PHP project and the researchers say updating is the only complete fix. If you need hours rather than minutes, the PHP advisory lists ways to narrow specific attack paths:

  • Set memory_limit=-1 in a way the application cannot override, for example php_admin_value in the FPM pool or Apache config. This removes the predictable memory-limit failure the first exploit relies on, but not every path to it.
  • Keep post_max_size conservative and limit request size, input nesting and multipart parts at the reverse proxy. If the site never accepts multipart form data, block it at the front end.
  • Set session.upload_progress.enabled=0. On 23 October the PHP project asked everyone to do this until the next regular release, because of a separate, less likely RCE vector (CVE-2026-115560) that still exists on the fixed versions.

Step 4: check whether anyone got in first

Patching closes the hole but does not remove anything an attacker left behind. For WordPress, these are the checks we run on our own hosts, all with WP-CLI inside the container:

  1. wp core verify-checksums --allow-root compares every core file with the copy on wordpress.org.
  2. wp plugin verify-checksums --all --allow-root does the same for plugins from the wordpress.org directory. Premium and custom plugins are skipped with a 404 warning, so review those separately. A mismatch is not proof of compromise, since some vendors patch bundled libraries, but every mismatched file deserves a look for eval, base64_decode or gzinflate on request input.
  3. find wp-content/uploads -name "*.php*" finds PHP files in the uploads folder, where code should not live. Some security plugins keep their own config there, so check each result before deleting it.
  4. List PHP files changed since 20 October and match them against the updates you know you installed.

The second bug can leak worker memory, according to the researchers. If a site stayed unpatched and reachable after the 21 October disclosure, rotate what that memory may have held: the WordPress salts in wp-config.php, database passwords, SMTP credentials and payment or email API keys.

Update, 27 October 2026, Windows only: on 26 October the PHP project published rebuilt Windows packages 8.5.12-1, 8.4.27-1, 8.3.36-1 and 8.2.35-1. They bundle Brotli 1.2.1, which fixes CVE-2026-111497, an out-of-bounds write that PHP says is reachable through the cURL extension when automatic HTTP response decompression is enabled. The PHP version number does not change, so on Windows check for the -1 package from the Windows downloads page, not just php -v. Linux and Docker builds are not part of this rebuild.

Frequently asked questions

Does updating WordPress fix PHP2Shell?

No. The flaws are in the PHP runtime. You need PHP 8.2.35, 8.3.36, 8.4.27, 8.5.12 or a distribution build with the backported fix, and then a restart or container rebuild so the web server uses it.

Is PHP-FPM safe?

No. The PHP project lists FPM as affected and the researchers confirmed RCE on it through application code paths. Red Hat says exploitation is harder on its default FPM setup than on mod_php, which lowers the risk but does not remove it.

My host says PHP 8.3.6 is patched. Is that right?

It can be. Ubuntu and other distributions fixed PHP2Shell by backporting the patch without changing the version number. Check the full package version against your distribution's advisory.

Which PHP versions are not fixed at all?

PHP 8.1 and older get no release from the PHP project. Only source backports, distribution builds and LTS vendors cover them.

Sources: PHP security advisory (21 and 23 October 2026), php2shell.com (Wiz Research, OpenAI Codex Security, Calif), Red Hat RHSB-2026-013, Ubuntu and Docker.

Running PHP sites in containers?

We build and run production infrastructure, including image rebuild pipelines that pick up security fixes without manual steps.

Cloud and DevOps services

Share This Article