CVE-2026-109619 — PHP Stale Internal Request-State Vulnerability

CVE-2026-109619

PHP - php2shell, Cross-Request Use-After-Free from State Surviving a Fatal Error

What is PHP?

PHP runs about 70 percent of the websites whose server-side language can be fingerprinted, and it is the foundation of WordPress, Drupal, Joomla, Magento, Nextcloud, and countless bespoke applications. It is also embedded, often invisibly, in network appliances and vendor management consoles.

What matters for this vulnerability specifically is how PHP is deployed. Under PHP-FPM, mod_php, or FrankenPHP, a pool of long-lived worker processes each handle request after request. PHP's design promise is that every request starts from a clean slate: memory allocated during a request lives in a per-request arena that is released wholesale at the end. A bug that lets state from one request survive into the next breaks that promise, and it breaks it between unrelated visitors on the same server.

Overview

CVE-2026-109619 is the second half of php2shell. Where its companion CVE-2026-109618 corrupts memory within a single request, this one reaches across the request boundary. A fatal error, in practice usually an attacker-forced out-of-memory condition, interrupts PHP before cleanup completes. Internal global structures are left holding pointers into the per-request memory arena. Request shutdown then frees that arena anyway. The worker process stays alive, and the next request it handles dereferences pointers to memory that has been freed and very likely reallocated with attacker-chosen contents.

That is a use-after-free with an unusually comfortable exploitation window: the attacker sends a first request to poison the worker, then a second request to groom the heap and trigger the reuse. No authentication and no user interaction are needed at any step, and the trigger happens inside PHP's own parsing, before any application routing.

NVD scores this 8.1 with AC:H, reflecting the heap grooming and worker-affinity requirements; the PHP project scores both php2shell issues CVSS v4.0 9.2. Note also a mapping disagreement in the published analysis: Red Hat, watchTowr, and CISA's own catalogue titles describe this CVE as the stale-state issue and CVE-2026-109618 as the in-request corruption, while Sansec and Wiz assign the specific upload-progress and fatal-error-backtrace bug chains the other way round. The practical guidance is identical either way, because the same releases fix both.

Affected Versions

Product Vulnerable Fixed
PHP 8.5 8.5.11 and earlier 8.5.12
PHP 8.4 8.4.26 and earlier 8.4.27
PHP 8.3 8.3.35 and earlier 8.3.36
PHP 8.2 8.2.34 and earlier 8.2.35
PHP 8.1, 8.0, 7.4 All (end of life) No upstream release; minimal source backports published, plus distribution and LTS vendor builds
PHP 7.3 and earlier All (end of life) No fix; migrate to a supported branch
RHEL 7 php package Affected by this CVE (unlike CVE-2026-109618) Vendor errata, or disable session upload progress

The vulnerable path dates to PHP 5.4.0, released in 2012, and is present in default configurations. All web SAPIs are in scope: PHP-FPM, Apache mod_php, php-cgi, FrankenPHP, and LiteSpeed. Verify the fix from the package changelog rather than the version string alone, for example rpm -q --changelog php-common | grep CVE-2026-109619 or the equivalent zgrep against the Debian changelog.

Technical Details

The CWE is CWE-416, use after free: the program keeps and later follows a pointer to memory it has already released.

Calif documents two concrete chains, one per deployment style. On Apache mod_php, a multipart file part can initialise the session through the session upload progress feature before module activation has finished. If parsing then hits a fatal, the session cleanup is skipped, but request shutdown still frees the heap, leaving session globals pointing at freed memory. A later multipart request without a file part reads and destroys that stale data. On PHP-FPM, a fatal during unserialize decoding skips php_var_unserialize_destroy(), leaving a dangling decoder pointer and a non-zero nesting level that a subsequent upload progress request reuses. A negative used_slots value in a destructor block then gives the attacker control over where a zval is written, which is the step that converts corruption into execution.

Session upload progress is enabled by default and is the confirmed path for this CVE; it is not the only one. The SAPI difference matters: PHP-FPM workers exit on an early initialisation failure, which is why CVE-2026-109618 is hard to exploit there, but a fatal raised after startup leaves the worker alive, which is exactly the condition this bug needs. A closely related third issue, CVE-2026-115560, covers a session upload progress serialisation-handler switch and is being fixed in a routine release.

Discovery

The php2shell pair was found by Calif, with OpenAI and Wiz also credited by the PHP project and Red Hat. The published write-up is by Ryan Austin (@lcfr_hax) of Calif, building on a long lineage: Stefan Esser's 2004 memory-limit RCE, PHP bug #78876 from 2020, and a 2024 OSTIF and Quarkslab audit that flagged a related out-of-memory issue without proving exploitation. This second bug was reported to the PHP project on 2026-08-21, ten days after the first. Volker Dusch of the PHP Foundation coordinated disclosure, and the release was pulled forward from 2026-10-22 to 2026-10-21 when the CVE identifiers leaked.

Exploitation Context

CISA added both php2shell CVEs to KEV on 2026-10-26 on evidence of active exploitation, with a three-day remediation deadline. watchTowr reported attack traffic against its Attacker Eye honeypots on release day, and Cloudflare began blocking attempts at 07:43 UTC on 2026-10-21. On 2026-10-24 a researcher at Perplexity published a confirmed honeypot RCE including an 800 KiB memory disclosure, though on an intentionally favourable single-worker mod_php target.

The counterweight is worth recording. Sansec tested the public proof-of-concept code and found it does not work against a default installation; most public PoCs additionally require a local file inclusion bug in the target application, and in some cases the tester had added one. No single universal request has been demonstrated, which argues against indiscriminate mass exploitation even while targeted exploitation is real.

Censys counts more than 32.51 million PHP services still on an affected version. No threat actor has been attributed and no ransomware use has been reported. Note that a WAF sitting in front of the application cannot see this: the vulnerable code runs inside PHP before application code, which is why Sansec states plainly that its own Shield product does not cover this layer.

Remediation

  1. Update to PHP 8.5.12, 8.4.27, 8.3.36, or 8.2.35, then confirm the CVE appears in the installed package changelog. Patching is the only complete fix.
  2. Inventory every PHP interpreter, including those bundled inside appliances, vendor consoles, and third-party container images, and check vendor advisories where PHP is embedded.
  3. If you run PHP 8.1 or earlier, apply a distribution or LTS vendor backport, or follow CISA's instruction to take the system offline until it can be moved to a supported branch.
  4. Until patched, set session.upload_progress.enabled = 0. This is the single most effective mitigation for this CVE and fully removes the RHEL 7 exposure, but it does not close every path. The directive is commented out in the shipped php.ini, so it must be added explicitly.
  5. Add memory_limit = -1 only where an external cgroup or container limit is enforced, reduce post_max_size to 8M or 32M with upload_max_filesize below it, and on PHP 8.5 set fatal_error_backtraces = 0. Apply with php_admin_value and restart workers, since a reload does not pick these up.
  6. Where file uploads are not needed, block multipart/form-data request bodies at nginx or Apache. Test a checkout or form submission afterwards, because this breaks more than uploads.
  7. Reduce worker lifetime so poisoned state is discarded quickly: lower pm.max_requests in the PHP-FPM pool. This narrows the window rather than closing it.
  8. Hunt for PHP worker processes spawning shells or fetching remote tools, for repeated multipart POSTs that trip the memory limit, and for abnormally large responses indicating memory disclosure. CISA publishes SIGMA rules for this in its GitHub repository.
  9. Federal civilian agencies must remediate by 2026-10-29 under BOD 22-01.

Key Details

PropertyValue
CVE ID CVE-2026-109619
Vendor / Product PHP Group — PHP
NVD Published2026-10-21
NVD Last Modified2026-10-27
CVSS 3.1 Score8.1
CVSS 3.1 VectorCVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H
SeverityHIGH
CWE CWE-416 find similar ↗
CISA KEV Added2026-10-26
CISA KEV Deadline2026-10-29
Known Ransomware Use No

CVSS 3.1 Breakdown

Attack Vector
Network
Attack Complexity
High
Privileges Required
None
User Interaction
None
Scope
Unchanged
Confidentiality
High
Integrity
High
Availability
High

Required Action

CISA BOD 22-01 Deadline: 2026-10-29. Apply mitigations in accordance with vendor instructions, ensuring compliance with CISA’s BOD 26-04 Prioritizing Security Updates Based on Risk (see URL in Notes) guidance and CISA’s “Forensics Triage Requirements” (see URL in Notes). Follow applicable BOD 26-04 guidance for cloud services or discontinue use of the product if mitigations are unavailable. Stakeholders are responsible for evaluating each asset's internet exposure and ensuring adherence to BOD 26-04 patching guidelines.

Timeline

DateEvent
2026-08-01Calif researchers identify several independent paths from an interrupted request to code execution
2026-08-21The second of the two php2shell bugs reported to the PHP project
2026-10-20CVE identifiers leak ahead of the embargo; PHP brings the release forward
2026-10-21PHP 8.5.12, 8.4.27, 8.3.36 and 8.2.35 released; CISA issues an alert the same day
2026-10-21Cloudflare reports blocking attack traffic from 07:43 UTC, before most sites had patched
2026-10-24Successful php2shell RCE with memory disclosure confirmed against a honeypot
2026-10-26Added to CISA Known Exploited Vulnerabilities catalog
2026-10-29CISA BOD 22-01 remediation deadline