wp-config.php » PHP RCE CVE-2026-109618 & 109619: Patch PHP for WordPress

PHP RCE CVE-2026-109618 & 109619: Patch PHP for WordPress

On October 21, 2026 the PHP project shipped an emergency security release for two critical bugs, CVE-2026-109618 and CVE-2026-109619. Both can allow unauthenticated remote code execution. That means an attacker can run code on your server without logging in. This is not a WordPress bug and not a plugin bug. Any server that handles web requests with PHP is affected, whether it uses PHP-FPM, Apache with mod_php, php-cgi, FrankenPHP or LiteSpeed. That covers every WordPress site on an unpatched PHP build.

WordPress.org published its own advisory the same day. It says no WordPress update is needed or planned, and that the fix is updating PHP itself. Updating plugins won’t help, and neither will a WordPress security plugin. As of 2026-10-23, here is exactly what I’m doing on the servers I manage.

According to the php.net security announcement, the patched releases are:

  • PHP 8.5.12
  • PHP 8.4.27
  • PHP 8.3.36
  • PHP 8.2.35

PHP 8.1 and older get no more official releases. If your site is still on 8.1, 8.0 or 7.4, you depend on your Linux distribution or an LTS vendor having backported the fix. PHP.net also published minimal source backports for 7.4, 8.0 and 8.1, for people who build PHP themselves. Realistically, this is the moment to move those sites to 8.2 or newer.

PHP rates Apache with mod_php as the highest-risk setup. It has a demonstrated exploit in which one unauthenticated request triggers the bug before any application code runs. On those servers, WordPress never gets a chance to do anything.

In wp-admin, go to Tools → Site Health → Info → Server and look at the PHP version. That’s the version the web server uses. It isn’t always the same as the php binary in your shell, so on a server I check both:

# CLI version (also what WP-CLI uses)
php -v
wp eval 'echo PHP_VERSION . PHP_EOL;'

# Is Apache loading mod_php? (highest risk)
apachectl -M 2>/dev/null | grep -i php

# Which PHP-FPM services are running?
systemctl list-units --type=service | grep -i fpm

One gotcha: Debian, Ubuntu and RHEL-based distros often backport security fixes without changing the upstream version number. So a version like 8.3.x below 8.3.36 doesn’t automatically mean you’re vulnerable, and you can’t confirm the patch from the version string alone. Check the package changelog for the October 21 fix, or ask your host directly.

Back up first. Snapshot the server if you can, or at least make a files and database backup. Then install the updated packages. Adjust the version numbers below to the branches you actually run.

# Debian / Ubuntu
sudo apt update
sudo apt install --only-upgrade 'php8.3*'
apt changelog php8.3-fpm | head -n 30   # look for the CVE IDs
sudo systemctl restart php8.3-fpm
sudo systemctl restart apache2          # if you use mod_php

# RHEL / Alma / Rocky
sudo dnf upgrade 'php*'
sudo systemctl restart php-fpm httpd

The restart matters as much as the update. Until you restart, the old workers keep running the vulnerable binary from memory. The second bug is literally about stale state surviving between requests in the same worker. After the restart, reload Site Health and confirm the version or package build.

If you install PHP from rpms.remirepo.net, note that php.net says the volunteer-run repo will not have updates on the release date. It recommends switching to distribution packages or building from source.

On shared or managed hosting, you usually can’t do this yourself. Open a ticket, ask whether the October 21 PHP security release has been applied to your server, and while you’re at it, move any site still on PHP 8.1 or older to 8.2+.

PHP.net lists a few settings that block specific attack paths. It is very clear that they do not make an installation safe, so use them only as a stopgap until you patch.

See also  5 (Less known) WordPress Security Tips to keep your website safe from hackers 💁

For CVE-2026-109619 (stale global state), turn off session upload progress. It has to be set before request parsing, so put it in php.ini, the FPM pool or the server config. Setting it in ini_set() or a .user.ini file won’t work.

; php.ini
session.upload_progress.enabled = 0

; PHP 8.5 only
fatal_error_backtraces = 0

For CVE-2026-109618 (out-of-memory corruption), php.net suggests removing the PHP memory limit and keeping request sizes low. Set the memory limit with php_admin_value so that WordPress and plugins can’t override it:

; PHP-FPM pool, e.g. /etc/php/8.3/fpm/pool.d/www.conf
php_admin_value[memory_limit] = -1
php_admin_value[post_max_size] = 32M
php_admin_value[upload_max_filesize] = 16M

Use 8M for post_max_size if the site doesn’t accept uploads at all, and keep upload_max_filesize below post_max_size. Yes, this is the opposite of the usual advice to increase the upload limit, but only for the next few days. With php_admin_value in place, the WP_MEMORY_LIMIT constants have no effect. I explain how those constants normally work in WP_MEMORY_LIMIT vs WP_MAX_MEMORY_LIMIT. With no memory limit, use container or cgroup limits to protect the server’s availability. Don’t use RLIMIT_AS or RLIMIT_DATA, because php.net warns that they can trigger the vulnerable allocation failure. Restart PHP after every change.

If you’re behind Cloudflare, it deployed WAF rules for both CVEs on all plans. On Pro, Business and Enterprise, check that the Cloudflare Managed Ruleset is set to block, not just log. That’s an extra layer, not a fix.

If you run your own server on an old PHP branch and can’t upgrade right away, WordPress.org repeats the UK NCSC’s advice: consider taking the system offline until you can fully mitigate it.

In OpenPanel, go to PHP → Select PHP Version. Each domain has its own version dropdown, and bulk actions let you move several domains to a patched branch in one go. The page also flags domains that are on outdated or unsupported versions, which makes the PHP 8.1 stragglers easy to find. Switching rewrites the domain config and reloads the web server, so expect a brief blip. On OpenLiteSpeed or LiteSpeed you can’t set the version per domain; you change it on the Default PHP Version page instead. In cPanel, the equivalent is MultiPHP Manager, but either way the actual patched PHP packages have to be installed on the server by whoever runs it.

Both bugs are in how PHP handles memory after an error. In CVE-2026-109618, running out of memory can interrupt PHP while request data is only half set up, and the cleanup code then treats that data as valid. In CVE-2026-109619, request state survives after its memory has been freed, and a later request in the same worker can use it. Since this all happens before or underneath WordPress, only a patched PHP binary, running in freshly restarted workers, actually closes the hole. The mitigations work by removing the specific triggers that are known so far.

  • Stay on a supported PHP branch (8.2+ today). Check the WordPress PHP version usage stats to see how many sites are still behind.
  • Enable unattended security updates for distro PHP packages, and restart PHP-FPM afterward.
  • Prefer PHP-FPM over mod_php.
  • If a server stayed unpatched and exposed for a while, look for signs of compromise. My hacked WordPress cleanup guide covers what to check.

TL;DR: CVE-2026-109618 and CVE-2026-109619 are unauthenticated RCE bugs in PHP itself, not in WordPress. Update to PHP 8.5.12, 8.4.27, 8.3.36 or 8.2.35 (or your distro’s patched build), restart every PHP worker, and confirm the result in Site Health. If you can’t patch today, set session.upload_progress.enabled = 0, lock memory_limit to -1 via php_admin_value, and keep request sizes low. Those are stopgaps, not fixes.

Was this post helpful?

Leave a Comment

I enjoy constructive responses and professional comments to my posts, and invite anyone to comment or link to my site.

Recommended