DEV Community

Cover image for PHP2Shell: Your PHP App Can Be Secure—and Still Be Vulnerable
Bargan Constantin
Bargan Constantin

Posted on

PHP2Shell: Your PHP App Can Be Secure—and Still Be Vulnerable

You can lock down your WordPress admin panel, enable MFA, remove abandoned plugins, and review every line of your application's code. If the PHP engine beneath it is vulnerable, those precautions won't fix the engine.

On October 21, 2026, the PHP project released emergency updates for two critical vulnerabilities, CVE-2026-109618 and CVE-2026-109619. Both are rated 9.2 under CVSS v4.0. Researchers demonstrated that specially crafted requests could lead to unauthenticated remote code execution (RCE) or disclosure of sensitive process memory.

The findings are being called PHP2Shell. The practical question for anyone running a PHP service is straightforward: Which PHP runtime is actually serving your requests, and has it been patched?

The bugs sit inside the request lifecycle

Normally, PHP prepares internal data for a request, runs the relevant code, and cleans up afterward. The newly disclosed bugs involve what happens when that sequence is interrupted.

CVE-2026-109618 — out-of-memory handling. If a memory allocation fails at the wrong moment, PHP can enter cleanup with internal data only partly initialized. Code that assumes the data is valid may then corrupt memory.

CVE-2026-109619 — stale state across requests. An earlier request can leave behind references to memory that has already been freed. If the same worker processes a later request and touches those references before resetting them, an attacker may be able to turn that use-after-free into memory corruption or code execution.

Simplified PHP request-lifecycle diagrams for CVE-2026-109618 and CVE-2026-109619

These are simplified explanations, not exploit recipes. The published research describes multiple exploit paths and different requirements depending on configuration, PHP version, and application behavior.

The key point is that the vulnerable code lives inside PHP. Wiz demonstrated pre-authentication RCE against WordPress, Drupal, and Joomla deployments, but those products were examples, not prerequisites. A minimal PHP application can still expose the underlying runtime bug.

The PHP project's security advisory specifically calls out web-serving installations using PHP-FPM, Apache mod_php, php-cgi, FrankenPHP, and LiteSpeed. It considers mod_php especially high-risk because an exploit was demonstrated before application code executes.

That last detail matters: an authentication check inside your application cannot protect code that runs before your application gets control.

Which PHP versions have the fix?

The PHP project published these upstream security releases on October 21, 2026:

PHP2Shell fixed upstream PHP versions: 8.5.12, 8.4.27, 8.3.36, and 8.2.35

PHP branch Fixed upstream version
8.5 8.5.12
8.4 8.4.27
8.3 8.3.36
8.2 8.2.35

PHP 8.1 and older are end-of-life upstream. Some operating-system vendors and long-term-support providers offer patched, backported packages. If you're using one, check its actual security advisory: a vendor-patched package may retain an older-looking version number.

For unsupported installations without a trusted backport, plan a move to a supported PHP release. PHP 8.2 itself reaches end of life at the end of December 2026, so treating 8.2.35 as a permanent destination would be a mistake.

Check the PHP that's running, not just the PHP you installed

A quick version check is useful:

php -v
Enter fullscreen mode Exit fullscreen mode

It also has a trap: that command checks the CLI interpreter. Your web server could be using a different PHP-FPM pool, binary, container, or managed hosting runtime.

For example, in a Docker Compose deployment where the PHP service is named php:

docker compose exec php php -v
Enter fullscreen mode Exit fullscreen mode

And on a Linux host using PHP-FPM, you can start by locating the running workers:

ps -eo pid,args | grep '[p]hp-fpm'
Enter fullscreen mode Exit fullscreen mode

Neither command is a universal proof that every web worker is patched. Check the actual service or container image deployed behind each site, the installed package build, and the vendor's advisory. Redeploy or restart affected workers after applying the fix, then verify the running build again.

For a small deployment, this may take minutes. Across several hosts, staging environments, inherited websites, and containers pinned to old image tags, the inventory is often the harder part.

What I'd check today

  1. List internet-facing PHP services. Include WordPress sites, internal admin panels exposed through VPNs or proxies, containerized applications, and forgotten staging instances.
  2. Identify the web-serving PHP build. Don't rely on local development versions or a single php -v result.
  3. Apply the upstream fix or a confirmed vendor backport. Rebuild images where necessary, restart affected workers, and verify what is actually running.
  4. Review recent errors and suspicious traffic. Wiz recommends looking for unusual multipart requests, repeated memory-limit failures or HTTP 500 responses, unexpected PHPSESSID response cookies, and unexplained PHP worker churn. These are investigation clues, not proof of compromise.
  5. Keep WAF protections enabled, but patch anyway. Cloudflare reported deploying protections and observing attack traffic on October 21. Its own guidance still tells customers to update PHP.

If you can't patch immediately, follow the temporary exposure-reduction measures in the official PHP advisory. Some configuration changes block demonstrated attack paths, but PHP explicitly says that none is a complete substitute for updating. Avoid treating a single WAF rule or INI setting as a fix.

Does PHP2Shell really affect 70% of the internet?

You'll see that figure in headlines. W3Techs reported roughly 69% PHP usage in October 2026, but its denominator is websites whose server-side programming language it can identify.

That percentage is not a count of unpatched servers. It certainly isn't a count of compromised sites. Actual exposure depends on PHP versions, runtime configurations, and applied vendor fixes.

The risk is serious enough without turning a usage statistic into an incident statistic.

Why AI is part of this story

Researchers at Wiz describe using frontier AI models alongside debugging and testing tools to discover, develop, and validate exploit chains. The underlying memory-safety bugs had existed for years. The hard part was chaining them into reliable behavior across different environments.

AI-assisted research helped reduce that effort. The same development should concern both attackers and defenders: difficult bugs may become easier to investigate, reproduce, and exploit. In this case, PHP maintainers and infrastructure providers also collaborated on patches and protections before public disclosure.

Teams using PHP, .NET, Node.js, and other runtimes face the same inventory problem. A clean application dependency scan doesn't tell you whether the interpreter, base image, or web worker underneath is safe.

A change to composer.lock cannot close PHP2Shell if the live PHP worker still runs an old build. Finish with evidence from the deployed runtime, not just a merged pull request.


Sources

Top comments (0)