Skip to content
Skip to content

Independent e-magazine

the OUTSPOKEN digest

PHP2Shell Explained: Two Critical PHP Flaws That Can Hand Over a Server

PHP's own engine, not any one app, carries two memory bugs rated CVSS 9.2. Here is what they do, which versions are hit and what the patched releases fix.

Outspoken Digest Technology Desk

Thursday, October 22, 2026/3 min read

PHP source code in a dark-themed code editor, with class methods and string replacement calls visible, a screenshot from 11 February 2017 of MediaWiki code, a file image illustrative of PHP code and not of the vulnerable code
Photo: Webysther via Wikimedia Commons (CC BY-SA 4.0)

Most of the web runs on PHP, and on 21 October the people who maintain PHP told everyone to stop what they were doing and update. The project shipped PHP 8.5.12, 8.4.27, 8.3.36 and 8.2.35, and its security advisory said the releases fix two critical vulnerabilities that can allow unauthenticated remote code execution.

The pair, CVE-2026-109618 and CVE-2026-109619, goes by the nickname PHP2Shell. Security researcher Kirill Firsov coined it for an exploit chain he demonstrated on video, according to Tenable's FAQ. The bugs were credited to researchers at Calif, OpenAI and Wiz, and the full story of the leak that followed is in our timeline of PHP2Shell.

What is PHP2Shell?

It is two flaws in the PHP runtime itself, the engine that reads a web request and runs the code behind a page. PHP says each is rated 9.2 on the CVSS v4.0 scale, which sits in the critical band. An attacker needs no password and no user to click anything.

The affected setups are all the usual ones: PHP-FPM, Apache with mod_php, php-cgi, FrankenPHP and LiteSpeed. The PHP security team says it considers the risk highest for mod_php, where a demonstrated exploit can fire before any application code has run.

What do the two bugs actually do?

Both bugs come from how PHP behaves when it runs out of memory partway through setting up a request. PHP describes CVE-2026-109618 as out-of-memory handling that can interrupt PHP while internal request data is only partly initialised, so cleanup later treats invalid data as valid. It describes CVE-2026-109619 as request state that survives after its memory has been freed, which a later request on the same worker can then use.

Wiz Research, in its write-up, ties this to two features most people never think about. PHP parses multipart/form-data requests, the format used for file uploads, before its modules finish starting up. The session upload-progress feature can publish a session identifier at that early stage. If an out-of-memory error aborts the request, that identifier can point at freed memory, and a later multipart request on the same worker can trust it. Wiz says this works even when the application never calls session_start().

The researchers also describe the chain differently from PHP's neat two-line summary. Wiz counts four bugs under two CVEs, and Calif, in its own technical account, walks through a stale hash bucket left by a memory-limit failure and stale decoder state left by an interrupted unserialize. The write-ups group the pieces in different ways, so the CVE labels and the researchers' bug names do not line up one to one.

How bad is a CVSS 9.2, and which versions are affected?

Early posts circulated a score of 10.0. Tenable reports that the PHP Foundation called that wrong, and the official figure is 9.2. Red Hat has taken a more cautious view of the first bug: its CVE page lists a CVSS 3.1 score of 8.1 and says reliable exploitation needs precise heap manipulation and timing, and that standard RHEL deployments use PHP-FPM, where workers exit on early failures.

The version range is the murkiest part. Wiz says nearly every PHP version back to 5.4 is affected by at least one of the issues. Calif dates the earliest affected code path to 5.4.0, though it gives a narrower version for the mod_php route. PHP itself published fixes only for the 8.2 to 8.5 branches, plus minimal source backports for 7.4, 8.0 and 8.1. Anything older gets no fix from the project.

Why does a PHP engine flaw hit every app on top of it?

Because the bug lives below the application. PHP parses the incoming request before WordPress, Drupal or a custom shop gets to look at it, so a login wall, a plugin firewall or careful coding never gets a say. Wiz said even a plain Hello World page on an affected version can be vulnerable, and it demonstrated unauthenticated code execution on current WordPress, Drupal and Joomla container images.

That is why updating the application does not help. The fix has to go into PHP, then every PHP process has to restart. Our companion pieces cover who is exposed and what site owners should do now.

The next few days will show how many of the early attempts worked, and how quickly the long tail of older servers gets patched or pulled offline.

Published in The Outspoken Digest

Editorial desk

Outspoken Digest Technology Desk

Software, hardware, artificial intelligence and what they change for everyone else.

Newsletter

The Digest, in your inbox

One edition, sent when it is ready. No noise, and your address is never passed on.

We send a confirmation first. One click to leave, always.

Share this story

the OUTSPOKEN digest

Beyond boundaries. Independent stories on technology, culture, and the trends shaping how we live.