
TL;DR
PHP2Shell refers to two critical PHP runtime vulnerabilities, CVE-2026–109618 and CVE-2026–109619, that can enable unauthenticated remote code execution. Disclosed on October 21, 2026, the flaws expose vulnerable PHP deployments to attacks that may execute before application-level security controls take effect. More concerningly, AWS detected an exploitation attempt four days before public disclosure, while Cloudflare prepared WAF protections for the release. The incident highlights a shrinking window between vulnerability discovery, exploit availability, and real-world targeting. Upgrade to a fixed PHP release and investigate potentially exposed systems.
Discovery, Disclosure Leak, and the Race to Patch
On October 21, 2026, the PHP project disclosed two critical vulnerabilities, CVE-2026-109618 and CVE-2026-109619, collectively known as PHP2Shell. Both can enable unauthenticated remote code execution (RCE), potentially allowing attackers to execute commands on vulnerable servers without application credentials. Because the flaws affect PHP's request-processing internals, they can be exploited before application-level security controls are reached.
The vulnerabilities emerged from multiple research efforts. Calif researcher Ryan Austin reported the first issue to the PHP security team on August 11, 2026, following research conducted through OpenAI's Patch the Planet program. Wiz Research independently identified related flaws later that month, and OpenAI's Codex Security team subsequently reported additional attack paths.
The planned disclosure was disrupted on October 20, when details about the vulnerabilities and a proof-of-concept (PoC) demonstration began circulating publicly ahead of schedule. The PHP team moved the release forward, publishing security updates on October 21.
The threat was not merely theoretical. Amazon Threat Intelligence reported an exploitation attempt against its MadPot honeypot on October 17, four days before public disclosure. Cloudflare also reported attack traffic and deployed Web Application Firewall (WAF) protections ahead of the release.
PHP2Shell Disclosure Timeline
| When (UTC) | What happened |
|---|---|
| August 11 | Calif reports the first vulnerability to PHP. |
| August 24 | Wiz Research reports related vulnerabilities. |
| October 17 | AWS detects an exploitation attempt in its MadPot honeypot. |
| October 20 | A Hacker News post hints at critical PHP vulnerabilities. |
| October 20 | PHP announces an emergency release after details leak ahead of the planned disclosure. |
| October 21 | Cloudflare's WAF protections go live. |
| October 21 | Some government organizations take websites offline as a precaution. |
| October 21 | PHP Foundation publishes both security advisories on GitHub. |
| October 21 | Fixed PHP versions are released. |
Affected Versions, Platforms, and Impact
Any server using PHP to handle web requests may be vulnerable, including deployments using PHP-FPM, Apache with mod_php, php-cgi, FrankenPHP, and LiteSpeed. The PHP team confirmed working exploits against default configurations (GHSA-w8hw-w9fx-j79w).
Affected Versions
- PHP 8.2 before 8.2.35
- PHP 8.3 before 8.3.36
- PHP 8.4 before 8.4.27
- PHP 8.5 before 8.5.12
Unsupported PHP versions may also be affected. Linux distributions sometimes backport security fixes without changing the upstream version number, so check your vendor's advisory before determining whether a system remains vulnerable. See Ubuntu USN-8948-1 for an example.
Impact: Successful exploitation can allow unauthenticated remote code execution with the privileges of the PHP process, potentially exposing application secrets, database credentials, and customer data. Consult the official PHP security advisory for the technical details and remediation guidance.
Applications Tested with Confirmed RCE
Calif also confirmed pre-authentication remote code execution against the following applications and versions running vulnerable PHP builds:
- WordPress 7.1.2
- Drupal 11.4.3
- Joomla 6.1.4
- MediaWiki 1.46.2
- Roundcube 1.7.4
- Magento 2.4.9
- phpMyAdmin 5.2.3
- Nextcloud 35.0.1
- Laravel 13.11
- Symfony 8.1
- WHMCS
These are tested application versions, not the only versions at risk. PHP2Shell affects the underlying PHP runtime, so updating the CMS or framework alone does not remediate the vulnerability. The PHP runtime itself must be patched.
How to Fix PHP2Shell (CVE-2026-109618, CVE-2026-109619)
Updating PHP is the only complete fix. Upgrade to PHP 8.5.12, 8.4.27, 8.3.36, or 8.2.35, as appropriate for your branch, or install your vendor's patched package. For PHP 8.1 and older, check vendor security advisories for backported fixes or migrate to a supported release. Rebuild container images and restart all affected PHP workers after updating.
If immediate patching is not possible, the following measures may reduce exposure. They are temporary mitigations, not substitutes for updating.
CVE-2026-109618: Out-of-Memory (OOM) Corruption
- Where operationally safe, set and enforce
memory_limit=-1in administrative configuration. This removes the predictable per-request memory limit used by the confirmed exploitation path, but does not prevent every possible allocation failure. - Keep
post_max_sizeconservative and enforce decoded request-body limits at the web server or reverse proxy. - Bound input-variable counts, nesting depth, multipart parts, per-part headers, and uploaded files.
- If the application does not require multipart uploads, block
multipart/form-datarequests before they reach PHP. - Do not use
RLIMIT_ASorRLIMIT_DATAas mitigations for this issue; these can trigger the vulnerable allocation-failure path.
CVE-2026-109619: Stale Global State
- Disable session upload progress if it is not required:
session.upload_progress.enabled = 0 - On PHP 8.5, set
fatal_error_backtraces=0to remove the producer used in the confirmedmod_phpexploitation path. - Remove obsolete or invalid INI directives that generate diagnostics before request initialization.
- Review attacker-reachable paths for fatal errors and timeouts that can interrupt operations before internal state is reset.
- Where practical, consider
pm.max_requests=1for PHP-FPM worker recycling. This is a supplementary risk-reduction measure, not a complete mitigation.
Apply mitigations administratively so applications cannot override them, and restart the affected workers. Follow both official advisories for additional conditions and limitations.
Technical Deep Dive: Inside PHP2Shell
PHP2Shell is not a vulnerability in WordPress, Laravel, or another PHP application. The root cause lies in PHP core, where request initialization, memory management, and cleanup do not consistently maintain valid internal state when execution terminates unexpectedly.
The two CVEs represent different manifestations of this problem: CVE-2026-109618 involves partially initialized data after an out-of-memory condition, while CVE-2026-109619 involves stale references to memory that has already been freed. Both can lead to remote code execution under the appropriate conditions.
CVE-2026-109618: Remote Code Execution Through Out-of-Memory Corruption
Root cause: incomplete initialization followed by unsafe cleanup.
PHP manages memory for each request and performs cleanup when processing finishes. However, if an allocation fails during a sensitive initialization step, the runtime may terminate the current execution path before the associated internal data structures have reached a valid state.
PHP uses an emergency control-flow mechanism called zend_bailout(), implemented using longjmp() in relevant paths, to escape certain fatal conditions. Before the fix, this could interrupt initialization without ensuring that subsequent cleanup would safely handle partially initialized data.
The problem is not simply that PHP runs out of memory. It is that execution can be interrupted between changes to an internal data structure, leaving cleanup code to operate on state that it assumes is valid.
Where the problem occurs
One relevant area is PHP's internal hash-table management, which is used to represent arrays and other data structures. When entries are inserted, the runtime must maintain consistent metadata, allocate storage, and initialize entry fields.
If an operation fails after some internal bookkeeping has changed but before the entry is fully initialized, the structure may be left inconsistent. If PHP subsequently traverses or cleans up that structure without correctly accounting for the interrupted operation, it can access invalid data.
Multipart request parsing provides a remotely reachable route into these failure conditions. PHP processes request fields and file metadata before application code executes in certain server configurations. Excessive internal allocation can trigger an out-of-memory condition during this stage, exposing the unsafe cleanup path.
How the failure can lead to RCE
The vulnerability can be understood as a sequence of four events:
- An incoming request triggers memory-intensive processing.
- PHP encounters an allocation failure while internal state is only partially initialized.
- Emergency termination interrupts the normal initialization sequence.
- Request cleanup processes the invalid state, potentially corrupting memory in a way that can lead to code execution.
The exact outcome depends on the execution path and server configuration. The PHP team confirmed exploitable conditions, but this should not be interpreted as meaning every PHP deployment is equally exploitable.
CVE-2026-109619: Remote Code Execution Through Stale Global State
Root cause: request-owned memory remains referenced after being freed.
The second vulnerability involves a different memory-safety failure: a use-after-free.
PHP workers can process multiple requests over their lifetime. Although request-specific memory is released when a request ends, some runtime state persists at the worker level. Any persistent reference to request-owned memory must therefore be cleared or updated before that memory is released.
CVE-2026-109619 occurs when this lifecycle is not handled correctly. An interrupted operation can leave internal state accessible through a global reference even though the memory it points to has already been freed. A later operation may then consume the stale reference before normal request initialization resets it.
Where the problem occurs
The relevant code paths involve PHP's persistent runtime state, including session and error-handling state. The vulnerability is not simply that PHP retains globals between requests; persistent state is an intentional part of the runtime architecture. The defect is that a reference to request-owned data can survive beyond the lifetime of that data.
The PHP security advisory describes two important classes of early consumers:
- Configuration diagnostics: Certain warnings or deprecation messages generated while configuration is being applied can access stale error-related state before ordinary request initialization.
- Session upload progress: Multipart upload processing can reach session-related functionality before normal session initialization has completed. This can expose stale session or decoding state left behind by an interrupted earlier operation.
In the confirmed scenarios, the state-producing operation and the operation that consumes the stale reference can occur in different HTTP requests handled by the same worker. [2]
How the failure can lead to RCE
The underlying sequence is:
- A request modifies internal state that remains reachable through a persistent reference.
- An unexpected termination prevents the corresponding cleanup or reset from completing.
- PHP releases the request's memory, leaving the reference stale.
- The same worker processes another request and reaches an operation that consumes that reference.
- Under suitable memory conditions, the use-after-free can be leveraged for remote code execution.
The distinction between the two vulnerabilities is important. CVE-2026-109618 concerns inconsistent data during the same request's failure and cleanup path. CVE-2026-109619 concerns a reference that outlives its memory and is consumed later.
What the Fix Changes
Both vulnerabilities were addressed in the PHP security releases published on October 21, 2026. The corresponding upstream fixes are available in PHP 8.2.35, 8.3.36, 8.4.27, and 8.5.12.
At a high level, the fixes address unsafe state transitions during bailout and ensure that interrupted operations do not leave internal state in a form that later code incorrectly trusts. The common lesson is that error handling must preserve the same memory-safety invariants as the normal execution path.
Conclusion
PHP2Shell demonstrates how failures in memory management and exceptional control flow can undermine the security of an entire application stack. Because both vulnerabilities affect PHP core, the exposure extends across multiple frameworks, CMS platforms, and web server configurations.
The disclosure timeline also highlights the challenges defenders face when exploitation attempts precede public disclosure. Organizations should inventory their PHP runtimes, deploy fixed releases, rebuild affected containers, and investigate potentially exposed systems.
Updating PHP to a fixed version is the only complete fix. Updating WordPress, Laravel, or another PHP application alone will not resolve the underlying runtime vulnerabilities.


