Share
October 23, 2026

PHP2Shell: what CVE-2026-109618 and CVE-2026-109619 mean for your servers

TL;DR: Two critical bugs in the PHP engine, CVE-2026-109618 and CVE-2026-109619, went public on 21 October 2026. My short advice is to patch now. The press calls them PHP2Shell. An attacker needs no login, only network access to a PHP endpoint, and the worst result is code running as your web worker user. The fix is PHP 8.2.35, 8.3.36, 8.4.27 or 8.5.12, or the patched package from your distro. In my view the workarounds below are a short bridge, not a fix.

What is going on, in plain words

In my picture, PHP is a clerk at a service counter. Every visitor gets a fresh desk, and the clerk clears it when the visitor leaves. It works for us as long as the desk is set up fully and cleaned in the right order.

CVE-2026-109618 breaks the setup. A visitor brings a pile of forms so oddly shaped that the clerk runs out of space halfway through. PHP then aborts in a hurry, using a C call named longjmp(), and the desk stays half arranged. The cleanup routine starts anyway, and nothing in it checks whether the setup ever finished, so it keeps going as if the desk were perfectly ready. It trusts that everything is ready. So it reads things nobody ever put there.

CVE-2026-109619 breaks the cleanup. After a fatal error, or a warning that comes late, some of the clerk’s notes still point to a drawer that was already emptied. The next visitor goes to the same clerk, and the clerk follows those old notes before setting up the new desk. If an attacker filled that drawer first, the clerk follows the attacker’s notes.

Engineers know this class as use after free (CWE-416), and you’ve probably met it before. Both bugs sit in php-src, the core engine, and not in an extension or in your application. So even spotless code of ours leaves the server exposed. My source for all of this is the PHP team: advisories GHSA-w8hw-w9fx-j79w and GHSA-6wmf-4rv5-p3rp.

Why even TV news picked it up

On 21 October the story reached mainstream outlets. The Wall Street Journal, The Washington Post, the Associated Press and CNN all ran stories. The CNN piece appeared on a local TV station’s website, which is probably how it reached people who never read a security feed.

Three angles made it travel, in my reading. PHP runs on up to about 70 percent of websites, so a bug in the engine touches a big part of the web. The bugs were reportedly found with AI help, and I think journalists like that. And agencies told site owners to go offline if they couldn’t patch. That last one is rare, and my guess is it did most of the work, because anyone can understand it.

How the risk could play out

Both bugs get a CVSS 4.0 score of 9.2, which is Critical. Red Hat rates them lower, 8.1 on CVSS 3.1 and Important, because the attack is hard to pull off and RHEL defaults to PHP-FPM, not mod_php. To my mind both views are fair. The hard part is real, but the starting conditions are cheap.

In my reading of the advisories, nobody needs to log in or click anything. For our servers, a network path to a PHP endpoint is enough. The worst confirmed result is remote code execution as the web worker account, and that is where my worry starts. The second bug can also leak memory.

For 109618, the trigger is a crafted multipart request. Think of a body with no usable content length, parts with a huge number of headers, or many empty file fields with nested names. Such a request drives memory up to memory_limit while it still fits inside post_max_size. With Apache and mod_php this happens during automatic body parsing, so before any of your code runs. With FPM the child process simply exits, and to my knowledge nobody has shown a complete FPM exploit.

For 109619, the attacker needs two requests that land on the same worker. One leaves the stale pointer behind, and the other uses it. Confirmed paths are the PHP 8.5 fatal_error_backtraces feature and the session upload progress feature. This one has working remote code execution on FPM too, so our FPM pools are not safe either. Hiding errors with error_reporting, display_errors or the @ operator gives my servers no protection, and I’d not count on it for yours.

Is anybody exploiting it? As of 23 October, neither CVE is in the CISA Known Exploited Vulnerabilities catalog, and CISA saw no exploitation in its alert of 21 October. Security vendors report attempts, but no confirmed successful compromise has been reported. The researchers who found the bugs showed a working exploit, while PHP published no exploit code. The story is a few days old, so I’d recheck it before relying on any of this, and I’d probably do it daily.

How to fix it

Updating is the only complete fix for us, and PHP says so itself. No trick replaces it. The fixed versions came out on 21 October 2026: 8.2.35 for the 8.2 branch, 8.3.36 for 8.3, 8.4.27 for 8.4 and 8.5.12 for 8.5.

Older branches are affected too, which matters for our legacy boxes. PHP published source patches for 7.4, 8.0 and 8.1, and some distros fixed even older packages. There is no official lower bound, so my assumption for anything old is that it’s affected. PHP 8.2 also reaches end of life on 31 December 2026, which is one more reason to move.

First, find out what you really run. The php -v command only shows the CLI. To see what your web server uses, ask PHP from inside a web request:

PHP
<?php
echo phpversion();

Open that page through the normal URL, read the version, then delete the file. In my opinion this is worth doing on every environment, including staging and container images, because those are the places people forget.

Packages are our second trap. Distros keep the old upstream version string after patching. Ubuntu 24.04, for example, fixed the bug in 8.3.6-0ubuntu0.24.04.13, which still looks like 8.3.6. So we compare the package release with the distro tracker, and we don’t trust php -v alone.

Status on 23 October:

  • Official Docker php images were updated to the fixed versions on 21 October.
  • Debian bookworm and trixie are fixed. Forky was still vulnerable.
  • Ubuntu 22.04, 24.04, 26.04 and 26.10 are fixed, with ESM fixes for older releases.
  • RHEL 8, 9 and 10 have fixes, except RHEL 9 with the php:8.4 stream, which was still marked as affected.

If you can’t update today

These settings reduce our risk. They don’t remove it. For 109618, PHP suggests setting memory_limit to -1 where applications can’t override it, and keeping post_max_size low: 8M without uploads, 32M with them. It also advises against RLIMIT_AS and RLIMIT_DATA on the process. Frontend limits on body size and on the number of multipart parts help too. For 109619, turn off session upload progress, and on PHP 8.5 turn off fatal error backtraces:

INI
; 109618
memory_limit = -1
post_max_size = 8M

; 109619
session.upload_progress.enabled = 0
fatal_error_backtraces = 0

They go into the startup config, and we have to restart all workers, because a changed value doesn’t reach workers that are already running. The last line applies to PHP 8.5 only. My preference is also to remove per-request INI changes, such as .htaccess or PHP_VALUE, where possible.

For logs, PHP suggests an isolated audit with log_errors on and E_ALL. Look for warnings that appear before your scripts run, fatal errors and “Maximum execution time exceeded”. A clean log proves nothing. It is not a green light, so in my view it is no sign of safety. CISA also advises watching for PHP worker processes that start shells or download tools. The UK NCSC advises checking for backdoors before you patch.

Where I’d start

Anything on Apache and mod_php that faces the internet comes first in my order, because that setup is the most exposed. FPM comes next, since 109619 works there too. After that I’d take cron boxes and CI images.

I’m not sure the “go offline if you can’t patch” advice fits every business. Still, an exposed server on an old PHP is a bet I’d rather not take, and my own rule is to patch first.

How fast does your team learn about a PHP security release? Where does it slip for you? What would you add to my list?