← All writing

PHP2Shell: The Critical PHP Flaw That Puts 70% of the Web in the Crosshairs

Two critical, unauthenticated remote-code-execution bugs in PHP's core engine (CVE-2026-109618 and CVE-2026-109619) were patched on October 21, 2026. Here's what they are, who is at risk, and why only an update fully fixes them.

· Updated 2026-10-24

  • PHP
  • Security
  • Vulnerability
  • RCE

On October 21, 2026, the PHP project released emergency patches for two critical vulnerabilities in the language's own engine - not in any framework, plugin, or application. Collectively dubbed PHP2Shell, the two flaws, tracked as CVE-2026-109618 and CVE-2026-109619, let a remote attacker execute arbitrary code on a server with no authentication at all. Both are rated 9.2 (Critical) under CVSS v4.0, and they affect nearly every PHP release from the past decade, back to PHP 5.4.

Because the bugs live in the engine that powers an estimated 70% of websites - WordPress, Drupal, Joomla, MediaWiki and far more - this is one of the most severe PHP issues in years. The fix is simple to state and urgent to act on: update the PHP runtime. No configuration change is a complete mitigation.

What actually went wrong

Both vulnerabilities share a single root cause in how PHP's core (the Zend engine) handles fatal errors. When a request hits a fatal condition - it exhausts its memory_limit, exceeds the max execution time, or the client connection drops - PHP does not unwind its call stack the normal way. It bails out abruptly, abandoning the execution context mid-function. Any internal data structure left half-built is simply discarded: no cleanup runs, and nothing records that it is incomplete. PHP then runs its ordinary teardown, which quietly assumes every structure is intact.

The two CVEs describe where that assumption breaks:

  • CVE-2026-109618 - RCE via out-of-memory corruption. A data structure is marked as containing an entry before the memory backing that entry is allocated. If that allocation is the one that crosses memory_limit, the entry is left holding stale heap bytes, and the failing request's own cleanup routine reads and branches on them.
  • CVE-2026-109619 - RCE via stale global state. A module-level global keeps pointing into per-request memory that shutdown has already freed, and still reports its operation as active. A later request handled by the same worker process reads or branches on that freed memory.

The kicker is where this happens in the request lifecycle. PHP parses incoming request data before extensions are initialized and before a single line of application code is compiled. That means exploitation is independent of what the server hosts - a perfectly maintained, up-to-date application is exposed to exactly the same degree as a neglected one. Researchers verified that a single anonymous POST can make an Apache mod_php worker spawn a shell and run an attacker-chosen command, with no login, no session, and no vulnerable app code involved.

Who is at risk

Every PHP installation serving web requests: PHP-FPM, Apache with mod_php, php-cgi, FrankenPHP, and LiteSpeed. The PHP team rates the risk highest for mod_php, where a demonstrated exploit triggers before any application code runs. Wiz Research additionally showed a Heartbleed-style memory-disclosure variant that can leak passwords, auth tokens, API keys, and certificates from worker memory - even without first achieving code execution.

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 no longer receive updates from the PHP project. Some distributions and long-term-support vendors have backported the fixes, so check your vendor (and the package changelog, not just the version string). The PHP team also published minimal source backports for 7.4, 8.0, and 8.1 for anyone building from source.

How to respond

The only complete fix is updating PHP. Updating WordPress or Laravel does nothing here - the vulnerability is in the runtime beneath them, supplied by the server package, host, or container image. If you cannot patch immediately, the PHP team and Wiz outline partial, time-buying mitigations, none of which close all paths:

  • For CVE-2026-109618: set memory_limit=-1 where applications can't override it, keep post_max_size low, and enforce request-size limits at the web server or proxy. Do not use RLIMIT_AS or RLIMIT_DATA as substitutes - PHP warns they can trigger the same vulnerable path.
  • For CVE-2026-109619: set session.upload_progress.enabled=0 and restart every worker (on PHP 8.5 also fatal_error_backtraces=0). This blocks a confirmed session path but not other variants.

Cloud and CDN providers - Cloudflare, Fastly, Google, AWS, Microsoft, Akamai, Imperva, Vercel - have published guidance or out-of-the-box mitigations for teams that need a stopgap while they patch.

Why this one matters beyond the patch

This is also a landmark for how vulnerabilities get found. The flaws had sat in the codebase for more than a decade, but the exploit chains required were at the edge of what human researchers could practically pull together. Frontier AI models did much of the work of finding and weaponizing them - Wiz Research used Google's Gemini alongside its own tooling, and an independent effort used OpenAI's models. The result: long-standing, latent flaws turned into working, in-the-wild exploits. Expect this to change how we think about the shelf life of any large, legacy codebase.

Bottom line: if anything you run touches PHP, update the runtime today. That's the entire fix.

Sources

Command palette

↑↓ navigate · Enter select · Esc close