How to patch WordPress for PHP2Shell (CVE-2026-109618 and CVE-2026-109619)

PHP2Shell is two critical PHP flaws. Which PHP versions fix them, what to set until you update, and how a Nextweb WordPress site moves to PHP 8.3.36.

· about 6 minutes to read

PHP2Shell is the name given to two remote code execution bugs in PHP that PHP disclosed on 21 October 2026. WordPress runs on PHP, so every WordPress site on an unpatched PHP is exposed, whatever its plugins and theme. This page says what the two bugs are, which PHP versions fix them, what to change while you update, and how a WordPress site on Nextweb moves to the fixed PHP, shown from a run on 25 October 2026.

What PHP2Shell is

PHP published the two advisories on 21 October 2026 and rates both Critical, with a CVSS 4.0 score of 9.2. Their own words, read on 25 October 2026:

  • CVE-2026-109618, "RCE via OOM corruption": "PHP uses longjmp() for out-of-memory (OOM) errors to exit the current context and abort handling of the request", and "In some contexts, request memory is temporarily reachable before it is fully initialized."
  • CVE-2026-109619, "RCE via stale global state": PHP's global state "must be reset before the request memory is released", and "The confirmed impact is unauthenticated heap use-after-free, memory disclosure and remote code execution".

Unauthenticated means a visitor needs no account on the site. The bugs are in PHP's handling of a request, before WordPress runs any of its code, so a WordPress update or a security plugin does not fix them.

Which PHP versions fix it

PHP's announcement of 21 October 2026 says that "PHP 8.5.12, 8.4.27, 8.3.36 and 8.2.35 fix two critical vulnerabilities that can allow unauthenticated remote code execution", and that "There are no complete mitigations, updating is the only safe choice."

Your PHP Move to
8.5 8.5.12 or later
8.4 8.4.27 or later
8.3 8.3.36 or later
8.2 8.2.35 or later
8.1 or older a supported branch

For 8.1 and older the announcement says they "no longer receive updates from the PHP project", and that PHP's security team "provided minimal source-backports for PHP 7.4, PHP 8.0, and PHP 8.1 to help people building from source". There is nothing from PHP for 5.6; Security fixes for PHP 5.6 after its end of life covers what Nextweb ported there.

To see which PHP a server runs, php -v answers for the command line. The PHP that serves the site can be a different build: its X-Powered-By response header, when the server sends one, names it.

In your terminal
curl -sI https://www.example.com/ | grep -i x-powered-by

What to set while you update

The announcement lists partial measures for a server that cannot update at once, and says they "do not make an installation safe". For CVE-2026-109619 it says: "Set session.upload_progress.enabled=0 and restart every worker. Use php.ini, an FPM pool or server configuration that applies before request parsing. Do not rely on ini_set() or FPM .user.ini." For CVE-2026-109618 it suggests memory_limit=-1 set where applications can't override it, and a low post_max_size. Nextweb's PHP 8.3.36, 8.5.12 and 5.6.40 packages ship with upload progress off; the older 8.3.9 package has it on.

On a managed host, the host updates PHP. Check that the version it moved you to is in the table above.

On Nextweb: new sites already have it

pkg install wordpress installs PHP 8.3.36 with WordPress since 23 October 2026, and a site deployed from it runs that PHP. Self-host WordPress on Linux without Docker shows the whole install.

On Nextweb: move a site deployed before 23 October

A site deployed earlier runs PHP 8.3.9, which both bugs affect. The run below started from that state: a Nextweb folder on Nextweb 1.0.0-beta.1.rc.8 (build 175) with WordPress 6.4.2, the package Nextweb offered before 17 October and still on the content server, and a site deployed from it. Like every Nextweb WordPress site before 23 October, it ran PHP 8.3.9:

You should see
$ grep -o 'runtime/php[^/]*/bin/php-cgi' nextweb_server/services.d/company-site.json
runtime/php8.3.9-linux-x64/bin/php-cgi
$ curl -sI http://127.0.104.10:4001/ | grep -i x-powered-by
X-Powered-By: PHP/8.3.9

Four commands moved it. First the fixed PHP, by its full name:

At the nextweb prompt
pkg install php8.3.36-linux-x64
You should see
Installation order: php8.3.36-linux-x64
Installing 1 package(s)...
...
php8.3.36-linux-x64 8.3.36 installed successfully

Then the WordPress package again. On this folder pkg upgrade answered "All packages are up to date", because the installed package is a different release from today's, so it comes out and goes back in. The same two commands replace 7.1.3's first revision, the one from 17 to 23 October. Removing the package leaves the site alone: a deployed site keeps its own copy of WordPress, and it kept answering throughout.

At the nextweb prompt
pkg remove wordpress
pkg install wordpress
You should see
Removed wordpress
...
Installing wordpress...
wordpress 7.1.3 installed successfully

The package installed today names PHP 8.3.36. reload is what moves the site to it: it rebuilds the site's PHP process from the package and records the new one.

At the nextweb prompt
reload company-site
You should see
Reloading site: company-site
Service mariadb: running (manage with "service mariadb status" / "service mariadb restart")
  Reusing site listen port 4001 for company-site
  Provisioning database for site company-site...
  ...
  Database wp_company_site and user wp_companysite ready
  Starting PHP runtime for site...
  php-cgi listening on 19100 (2 processes, opcache off)
company-site: re-provisioned at /home/you/nextweb/nextweb_server/sites/company-site/wordpress
Service company-site: registered (manage with "service company-site status" / "service company-site restart")
Webserver reloaded (site listen ports bound)
Visit: http://127.0.104.10:4001/

And the site's PHP afterwards:

You should see
$ grep -o 'runtime/php[^/]*/bin/php-cgi' nextweb_server/services.d/company-site.json
runtime/php8.3.36-linux-x64/bin/php-cgi
$ curl -sI http://127.0.104.10:4001/ | grep -i x-powered-by
X-Powered-By: PHP/8.3.36

verify company-site passed after it. The site's copy of WordPress, its database and its uploads stayed as they were; Nextweb wrote wp-config.php again, as it does at every apply.

Why this order

Install PHP first. reload stops the site's PHP before it starts the one the WordPress package names, so that PHP has to be installed already. In one of the two runs made for this page, pkg install wordpress fetched PHP 8.3.36 on its own; in the other the order it printed still named 8.3.9 and it did not. Installing PHP by name first works either way.

Two shortcuts do not work on a folder like this one:

  • pkg install php-runtime answered "php-runtime 8.3.9 is already installed" and installed nothing, because the PHP already installed answers to that name. Use the full name, php8.3.36-linux-x64.
  • Restarting Nextweb, or running apply, leaves a running WordPress site on the PHP it started with. Only reload <site> moves it.

Nextweb's WordPress sites run PHP 8.3.36. PHP 8.5.12 installs as a package, but a WordPress site does not use it yet.

Questions

Does updating WordPress fix PHP2Shell?

No. Both bugs are in PHP, in how it handles a request before WordPress runs any of its code. The fix is a PHP release: 8.5.12, 8.4.27, 8.3.36 or 8.2.35, or later in the same branch.

Is turning off session upload progress enough?

No. PHP says its partial measures do not make an installation safe. Turn upload progress off in php.ini while you update, then update PHP.

Which PHP does a Nextweb WordPress site run?

PHP 8.3.36 for a site deployed from 23 October 2026 on. A site deployed earlier runs PHP 8.3.9 until the new PHP and WordPress packages are installed and the site is reloaded, as this page shows.

Related: Self-host WordPress on Linux without Docker, Security fixes for PHP 5.6 after its end of life, The PHP packages.