NOW AVAILABLE: CONTINUOUS SECURITY TESTING SERVICES Learn More

Responder Guidance for PHP2Shell (CVE-2026-109618 and CVE-2026-109619)

Responder Guidance for PHP2Shell (CVE-2026-109618 and CVE-2026-109619)

Share

TL;DR
  • PHP runs much of the web. CVE-2026-109618 and CVE-2026-109619 affect its core engine, not any individual application, so a site does not need a particular feature or plugin to be at risk. If your site runs a vulnerable PHP version, an attacker who can reach it has a way in, so update PHP now. 
  • Both flaws enable unauthenticated remote code execution (RCE) and are fixed in PHP 8.5.12, 8.4.27, 8.3.36, and 8.2.35. Any vulnerable install is reachable, but whether that reach becomes code execution depends heavily on configuration: SAPI (highest risk under mod_php), opcache, display_errors, memory limits, and architecture. We examine partial mitigations here, but patch now because none of them is a complete fix.

Background

On October 21, 2026, the PHP project disclosed two critical memory-corruption vulnerabilities that can allow unauthenticated remote code execution. Both are fixed in PHP 8.5.12, 8.4.27, 8.3.36, and 8.2.35. Every PHP install serving web requests is in scope, regardless of the server API (SAPI) it runs under: PHP-FPM, Apache with mod_php, php-cgi, FrankenPHP, and LiteSpeed are all affected.

The vendor rates the risk highest for mod_php, where a single unauthenticated request can trigger the bug before any application code runs. The disclosure built on public research from several external teams, including Calif.io (whose write-up enumerates affected real-world applications) and Wiz. Public proof-of-concept exploits began circulating shortly afterwards, though their quality varies widely, and we reproduced unauthenticated RCE in our lab. Patch now; the interim mitigations below reduce specific attack paths but do not make an install safe.


How Exploitation Works

CVE-2026-109618: RCE via Out-of-Memory (OOM) Corruption

An attacker sends a request crafted to exhaust memory while PHP is still parsing it, for example a multipart POST that floods the parser with a large number of per-part header lines. PHP’s OOM handling interrupts parsing while internal request data (such as the $_POST array) is only partially initialized, and request cleanup then treats that invalid data as valid. That hands the attacker a corrupted-memory primitive that can be groomed into attacker-controlled execution. On mod_php this fires before any application code runs, so no account or app bug is required.

CVE-2026-109619: RCE via Stale Global State

When a request dies partway through, for example on an attacker-induced fatal error or timeout, some request-scoped internal state (PHP’s serializer state) can be freed while something still points at it. A later request handled by the same worker reuses that dangling state before normal per-request initialization resets it. By reaching the state through a feature that reads it back, such as session.upload_progress, the attacker turns the use-after-free into a forged object in session data that the engine dereferences into attacker-controlled execution. This path is also pre-authentication on mod_php.


Does Exploitation Require a Specific App Feature?

That depends on what you count as exploitation. No app feature gates these bugs, because the flaw is in the PHP runtime: an unauthenticated attacker can reach it against essentially any vulnerable install, whatever the application does. Whether that reach turns into remote code execution is the harder question, and it hinges on your specific stack, not on any single setting you can switch off.

Reachability is the easy part for an attacker. On mod_php, the vendor demonstrated an unauthenticated request that triggers the attack before any application code runs. CVE-2026-109618 fires in PHP’s core request parser. The confirmed CVE-2026-109619 path rides session.upload_progress, a default-on engine feature an attacker drives directly. On PHP-FPM and php-cgi, the same pre-application path only crashes a worker, which a production worker pool simply respawns, so that denial of service is not the exposure to plan around.

Code execution is where your application stack decides the outcome. There is still no feature to switch off, but opcache, display_errors, memory_limit, session handling, and how the app warms and reuses its workers all change whether a given exploit lands and how much an attacker must tailor it per target. In our testing, chains that fired reliably against a bare PHP image had to be re-tuned for real applications. That re-tuning raises the bar but does not remove the exposure, so treat any vulnerable version as exploitable and patch, rather than reasoning from what your app does or does not do.


Factors That Reduce Exposure or Raise the Bar

Each measure below reduces exposure by closing or complicating a specific attack path, though only patching is a complete fix.

  • Run PHP-FPM or php-cgi rather than mod_php where you can. The straightforward OOM trigger makes an FPM worker exit (denial of service), not execute code. An RCE path on FPM exists but is application-dependent, requiring the app itself to reach a vulnerable decode after startup. This raises the bar, but the vendor still considers all SAPIs at risk.
  • Set session.upload_progress.enabled = 0. This removes the confirmed CVE-2026-109619 delivery vector. Apply it before request parsing (php.ini, FPM pool, or server config), not via ini_set () or . user.ini. It blocks the confirmed session paths, but not every variant.
  • Set memory_limit = -1 and enforce it so apps cannot override it. This removes the attacker-tunable memory-limit failure used to drive the OOM. Do not substitute RLIMIT_AS/RLIMIT_DATA or an in-process cgroup kill, which reintroduce the allocation failure; use a container or cgroup boundary that kills only the affected worker.
  • Set a low post_max_size  and add request-shape limits at the proxy or web server. Cap decoded request size, input field count, multipart part count, header count, and nesting depth, including for requests with no usable Content-Length. These caps remove the most reliable way to drive the memory exhaustion that triggers CVE-2026-109618.
  • Set display_errors = Off at request start. The public session-based exploit leaks the memory addresses it needs out of an error message that PHP prints into the HTTP response while parsing the request. With errors suppressed before any app ini_set, the attacker loses that one-shot leak and must fall back to blind brute forcing. WordPress, Roundcube, and Joomla ship with this setting off. Hiding diagnostics neither fixes the bug nor blocks the OOM path, but it does deny the public session chain a clean leak it can use to defeat ASLR (Address Space Layout Randomization).
  • Set fatal_error_backtraces = 0 on PHP 8.5. This blocks the confirmed fatal-backtrace trigger for CVE-2026-109619, but only that path.
  • Keep ASLR enabled. It raises an attacker’s cost but does not stop exploitation. On Apache prefork, every worker inherits the parent’s memory layout, so the randomization is constant per master and a crashed worker respawns identically laid out. That hands an attacker a stable target to recover, by brute force or by a memory leak depending on the architecture. We confirmed RCE with ASLR enabled against a subset of stock PHP Docker images.
  • Opcache makes a reliable exploit harder. Most production deployments already run it. It shifts heap layout and breaks exploit arming calibrated against the stock, opcache-off php:* images, so an attacker has to recalibrate per target. That friction is incidental, so do not count it as a defense.
  • Architecture forces an attacker to re-tune per target. An exploit built for x86-64 or ARM/aarch64 has to be adapted for the other, which changes the request count and effort. On ARM, that re-tuning is a blind brute-force that crashes and respawns workers in detectable bursts; on x86-64, higher address-space entropy pushes an attacker to a quieter one-shot memory leak instead. Both are fully exploitable, so architecture is friction, not a barrier.
  • Remove attacker-reachable fatal errors, timeouts, and invalid per-request settings from your app. A request that dies partway through is what strands the stale state CVE-2026-109619 reuses, so an attacker who can force one has the trigger they need. Harden the places that fail mid-request: callbacks, file upload and import handling, and request cleanup.

What to Do Now

  • Patch to 8.5.12, 8.4.27, 8.3.36, or 8.2.35. For end-of-life (EOL) branches (7.4 / 8.0 / 8.1), apply your vendor’s backport or upgrade to a supported branch. Restart every worker after any change.
  • If you cannot patch immediately, layer the interim mitigations above, prioritizing hosts running mod_php.
  • A vulnerable version tells you a host is exposed and must be patched, but not how exploitable it is. That depends on the SAPI, configuration, and mitigations on the host in question, so patch every vulnerable host and use those factors to decide which to patch first.

Our Assessment

At the time of publication, our research team has reproduced full unauthenticated RCE (ASLR on, HTTP only, no debugger) against stock php:8.3, php:8.4, and php:8.5 Apache mod_php Docker images. Real application images that ship with opcache enabled force an attacker to recalibrate. FPM, in our testing of the direct OOM path, produces denial of service rather than code execution. We are continuing to research these issues and will update this guidance if our findings change it significantly.


Jon Williams

By Jon Williams

Staff Security Engineer

As a researcher for the Bishop Fox Threat Enablement & Analysis team, Jon spends his time hunting for vulnerabilities and writing exploits for software on our customers' attack surface. Jon has written and presented research on various topics including enterprise wireless network attacks, bypassing network access controls, and reverse-engineering edge security device firmware.


Banksy Fox exploder1

By Threat Enablement & Analysis Team

The Bishop Fox Threat Enablement & Analysis team researches emerging vulnerabilities, exploits, and attacker techniques to understand how new threats translate into real-world risk. The team combines vulnerability research, exploit development, threat intelligence, and offensive security expertise to analyze new disclosures, validate exploitability, and develop methods for identifying affected systems at scale.

Subscribe to our blog

Be first to learn about latest tools, advisories, and findings.