The PHP2Shell dossier

Two critical PHP runtime vulnerabilities disclosed together on 21 October 2026. This page keeps the technical facts, the affected surface, the fixes and the evidence boundaries in one place.

IdentifiersCVE-2026-109618 · CVE-2026-109619 Content updated23 October 2026, 15:45 UTC Source records48

Overview

PHP2Shell is the collective name for two vulnerabilities in the PHP engine itself. CVE-2026-109618 is an out-of-memory handling flaw; CVE-2026-109619 is a stale-global-state use-after-free. Both can lead to unauthenticated remote code execution in affected web-serving configurations.

The important sentence for a site owner is not “critical RCE”. It is “this is below your application”. A patched CMS, a current framework and a clean plugin inventory do not fix a vulnerable PHP binary. The update has to reach the runtime that serves the request, and every worker has to be restarted or replaced afterwards.

PHP published fixes in 8.2.35, 8.3.36, 8.4.27 and 8.5.12. PHP 8.1 and older are end-of-life and have no upstream release; the project published minimal source backports for 7.4, 8.0 and 8.1, and distributions or LTS vendors may provide their own. Those are different support paths and need different verification.

Verified identifiers

Record Identifier Vendor score Fixed in
RCE via OOM corruption CVE-2026-109618
GHSA-w8hw-w9fx-j79w
CVSS v4.0 9.2 8.2.35 · 8.3.36
8.4.27 · 8.5.12
RCE via stale global state CVE-2026-109619
GHSA-6wmf-4rv5-p3rp
CVSS v4.0 9.2 8.2.35 · 8.3.36
8.4.27 · 8.5.12

NVD separately publishes CVSS v3.1 9.8 for both records. That is a different scoring system, not a second vendor score. GitHub / PHP Security Team GitHub / PHP Security Team NIST NVD NIST NVD

The two flaws, separately

Treating the pair as one vulnerability loses the conditions that matter for mitigation. Each record below has its own trigger path and its own interim controls.

CVE-2026-109618 — OOM corruption

PHP uses longjmp() to exit on out-of-memory. During some contexts, request memory is reachable before initialisation completes. If an allocation fails then, cleanup can treat invalid memory as valid. PHP says multiple OOM strategies can reach remote code execution.

Full record: affected branches, conditions, controls →

CVE-2026-109619 — stale global state

Request-owned state can remain in worker globals after the request heap is freed. A later request handled by the same worker may read that stale state before initialisation resets it. Confirmed paths involve session upload progress and, on PHP 8.5, fatal-error backtraces.

Full record: worker reuse, controls, status →

Record Primary trigger in the advisory Confirmed paths / condition Interim control named by PHP
CVE-2026-109618 OOM exit while request data is partly initialised; cleanup then handles invalid state. Demonstrated pre-application execution with Apache mod_php; not every request or deployment is automatically exploitable. memory_limit=-1, conservative post_max_size, proxy request-shape limits and container memory boundaries.
CVE-2026-109619 Request-owned global state survives after the request heap is freed. Producer and consumer must reach the same worker; confirmed session upload-progress path; PHP 8.5 fatal-backtrace path. session.upload_progress.enabled=0; on 8.5 fatal_error_backtraces=0; restart every worker.

Both records were fixed together, but the trigger and interim controls differ. The table is a reading aid, not a substitute for the advisories; see the separate records.

Affected versions and deployments

PHP says all installations serving web requests are at risk, including PHP-FPM, Apache with mod_php, php-cgi, FrankenPHP and LiteSpeed. It rates Apache mod_php highest risk because a demonstrated attack can run before any application code executes.

Branch Affected Fixed Note
PHP 8.5< 8.5.128.5.12Upstream fix.
PHP 8.4< 8.4.278.4.27Upstream fix.
PHP 8.3< 8.3.368.3.36Upstream fix.
PHP 8.2< 8.2.358.2.35End of life 31 Dec 2026.
PHP 8.1 and olderNo upstream supportVendor / source backportWiz reports PHP 5.4+; CERT-EU says PHP 5 onward may be affected.

“Version” is not the same as “deployment”. Container images, appliances and managed hosting may bundle PHP separately from the site’s application code. PHP Group CERT-EU Wiz Research

Patch and vendor backports

The complete fix is a PHP release containing the patch. Distributions and LTS vendors received patches in advance, so the right evidence is the vendor advisory and the package changelog, not only the version string reported by a scanner. A backport can keep an older upstream version number while containing the fix.

After updating, restart every PHP worker, Apache process or container replica. A new binary on disk with an old worker serving traffic is not a patched service. The verification guide gives a concrete sequence and a record you can keep.

Interim controls and their limits

PHP lists interim controls because some organisations cannot update immediately. They reduce specific attack paths. They do not make an installation safe, and PHP says updating is the only complete mitigation.

Decision flow: if PHP serves web requests, check for a fixed release or verified backport; if patching is possible, update and restart workers; if not, apply interim controls, isolate and monitor.
Figure 2 — A decision flow for the patch window. Interim controls are a bridge, not an exit. Original diagram · PHP2Shell Live
  • OOM corruption: set memory_limit=-1 in a non-overridable place, reduce post_max_size, enforce request-shape limits at the proxy, and use a container or cgroup limit. Do not substitute RLIMIT_AS or RLIMIT_DATA.
  • Stale global state: set session.upload_progress.enabled=0 and, on PHP 8.5, fatal_error_backtraces=0. Apply before request parsing, not through ini_set() or .user.ini, then restart every worker.
  • Availability boundary: a WAF or reverse proxy can reduce exposure, but it is not a fix. Cloudflare’s own guidance says patch even with WAF protection.

The mitigation guide explains why memory_limit=-1 is not a contradiction, how to verify the effective values, and how to assess compromise without treating a clean log as proof.

Why WAF, backups or non-root are not enough

A WAF sees HTTP requests; these flaws execute inside the PHP worker. A rule can block known patterns and raise the cost of scanning, but a request that does not match reaches PHP. A backup restores availability after an incident; it does not stop code execution. A non-root PHP user limits the attacker’s next steps; it does not turn remote code execution into a non-event.

Each control addresses a different part of the risk. None of them changes the fact that the vulnerable code is in the runtime. That is why the site keeps patch status, exploitation status and KEV status separate instead of collapsing them into one “danger” label.

Common questions

If the database is on another server, are its credentials still at risk?

Short answer: Treat credentials readable by the PHP process as in scope until the runtime is patched and the evidence is reviewed. The advisories describe code execution, not a documented credential-theft campaign.

Conditions and what to check

Network separation does not erase the risk if the application can connect to the database. An attacker who executes code in the PHP process can use the application’s own configuration and environment. Patch first, then review access and authentication logs and rotate credentials according to your incident policy. This site has no evidence of a specific credential-theft campaign; the point is the access that code execution can provide.

GitHub / PHP Security Team GitHub / PHP Security Team

Does updating WordPress, a theme or a plugin fix PHP2Shell?

Short answer: No. The flaw is in PHP, below WordPress. Updating those components is normal maintenance, but the PHP runtime must be updated and every worker restarted.

Where the fix belongs

A CMS update changes application files, not the PHP binary or the workers serving requests. If your host manages PHP, ask which branch and package revision is running, when it changed and whether the service was restarted. The WordPress runtime check shows how to separate the two layers without exposing server configuration.

Why does php -v show a different version from the website?

Short answer: The command line and the web server can use different PHP binaries, php.ini files and process pools. php -v only describes the CLI.

How to compare them safely

Check the serving SAPI and its loaded configuration, not a public phpinfo() page. The verification guide lists commands for Apache, PHP-FPM and containers, including a restricted web check when the CLI is not conclusive.

How do I confirm the fix is active after restarting?

Short answer: Verify the process that serves requests, the package or image that contains the fix, and the restart time. A version string alone is not enough.

Evidence to keep

Record the service name, the runtime version and SAPI from the running process, the package changelog or image digest, and the restart or rollout time. A distribution backport may keep an older visible version while containing the fix. The verification guide has the full sequence.

Confirmed, reported, not established

Confirmed by primary sources

The two CVEs, their affected branches, fixed releases, CVSS v4.0 9.2, the interim controls and the statement that no configuration is a complete fix come from PHP and the GitHub advisories.

Reported by vendors and media

Amazon observed an attempt on 17 October. Cloudflare observed attack traffic before disclosure and a sharp rise afterwards. WatchTowr, Hadrian, Patchstack, VulnCheck and others reported attempts with different results. These are attributed reports, not site-wide victim counts.

Not established

A confirmed mass compromise of production sites. A precise number of affected organisations. A guarantee that every variant is covered by the interim controls. Whether an appliance or managed host has applied the fix without a vendor advisory. The absence of these facts is not evidence that the risk is lower.

Follow the record

  • Timeline — 18 dated events, with evidence category and direct sources.
  • News and updates — original summaries of what changed, not republished articles.
  • Guides — verification, mitigation and advisory reading.
  • Vulnerability library — PHP, Node.js core, npm and historical context.

Latest updates

Sources

This dossier draws on 48 source records, including the PHP advisories, GitHub security advisories, NVD, CERT-EU, the UK NCSC, Japan’s IPA, CISA’s KEV JSON feed, Cloudflare, Wiz, Bitdefender and reporting by The Record and SecurityWeek. Read scope is shown on the sources page.

Content updated23 October 2026, 15:45 UTC Research cut-off23 October 2026, 15:45 UTC VerificationConfirmed by primary source

Search PHP2Shell Live

Type to search the local index Results stay in your browser
↑ ↓ move Enter open Esc close