PHP2Shell: Critical PHP Vulnerabilities and How to Check if You're Affected
TL;DR
On October 21, 2026, Wiz Research disclosed PHP2Shell - two critical vulnerabilities in the PHP Zend Engine (CVE-2026-109618 and CVE-2026-109619). Unpatched PHP installations are exposed pre-auth and have a high likelihood of being vulnerable. CVSS 3.1: 9.8. CISA issued an emergency advisory the same day urging immediate patching. All PHP versions before 8.2.35, 8.3.36, 8.4.27, and 8.5.12 are affected. Within 24 hours of disclosure, our team built and validated automated attack simulations in Nemesis so our customers can verify their defenses are actually working - not just assumed to be.
UPDATE 2026-10-22: Patch Completeness Unclear and Active Exploitation
There are unconfirmed reports that the current patches are incomplete and active exploitation is ongoing. Therefore we recommend to evaluate if attack vectors required for exploitation such as POST requests can be turned off at least temporarily.
CISA Advisory: Immediate Patching Required
CISA published a critical alert on October 21, 2026, titled "Critical Vulnerabilities in PHP Require Immediate Patching" (full advisory). Key points from CISA:
"CISA strongly urges organizations to immediately patch the recently disclosed critical vulnerabilities in PHP, CVE-2026-109618 and CVE-2026-109619. These vulnerabilities, known as 'php2shell,' allow for unauthenticated remote code execution in PHP and affect all PHP installations serving web requests."
CISA's recommended actions:
Identify and inventory systems running any version of PHP. PHP is often a component of other software and prevalence may not be directly observable.
Apply the patch immediately, prioritizing internet-facing systems.
Take unpatched systems offline if you cannot update immediately or run PHP 8.1 or earlier (unsupported).
Deploy a WAF as temporary protection until systems are patched.
Monitor for suspicious activity, including PHP worker processes launching shells or downloading tools.
While CISA has not observed active exploitation at time of publication, unpatched installations are at high risk given the low complexity of the attack and the availability of public proof-of-concept code.
What Is PHP2Shell?
PHP2Shell refers to two related vulnerabilities in PHP's core request-handling code:
CVE-2026-109618 - Memory corruption via multipart/form-data parsing (OOM bailout leading to Use-After-Free)
CVE-2026-109619 - Session file poisoning via PHP_SESSION_UPLOAD_PROGRESS
Unpatched PHP installations serving web requests are exposed to these vulnerabilities without authentication. The attack requires only a crafted HTTP request. While not every PHP application may be exploitable in every configuration, the vulnerabilities are in the PHP engine itself, and the likelihood of a given unpatched installation being vulnerable is high.
Affected Versions
PHP Branch | Vulnerable Versions | Patched Version |
8.2.x | Below 8.2.35 | 8.2.35 |
8.3.x | Below 8.3.36 | 8.3.36 |
8.4.x | Below 8.4.27 | 8.4.27 |
8.5.x | Below 8.5.12 | 8.5.12 |
8.1.x and earlier | All versions (EOL) | No patch available |
This affects Apache with mod_php, PHP-FPM behind nginx or Apache, and any other SAPI. PHP 8.1 and earlier are end-of-life and will not receive patches - CISA recommends taking those systems offline.
Understanding the Attack: CVE-2026-109618
The Mechanism
The more severe of the two vulnerabilities exploits a flaw in PHP's multipart/form-data parser (rfc1867.c). Here is how it works:
Bypassing upload limits: When a file upload control in a multipart POST has an empty filename (filename=""), PHP skips the max_file_uploads counter but still registers 6 internal variables per control via php_register_variable_ex(). An attacker can include thousands of these controls in a single request.
Heap amplification through nesting: Each control uses deeply nested array keys (e.g., f[0_0][0_1]...[0_59]). PHP allocates a HashTable structure at each nesting level - roughly 350 bytes per level. With 4,000 controls and 60 levels of nesting, a 2.5 MB HTTP request inflates to approximately 128 MB of heap memory - a 53x amplification factor.
Triggering the crash: When this heap allocation exceeds PHP's memory_limit (128 MB by default), the Zend Engine calls zend_bailout(), which executes a longjmp to abort the request. This longjmp skips the normal cleanup of the HashTable structures that were being built.
Use-After-Free: The skipped cleanup leaves dangling pointers in the HashTable arData buckets. During request shutdown, zend_array_destroy() attempts to free these already-invalid pointers - a classic Use-After-Free condition that can be leveraged for remote code execution.
Why This Is Serious
No authentication required. The attack is a single HTTP POST request.
Trivial to exploit. Public proof-of-concept code exists. The payload is straightforward to generate.
Denial of Service is the minimum impact. Even without achieving code execution, the OOM condition crashes the PHP worker process handling the request.
Mass exploitation is likely. The attack pattern is simple enough for automated scanning at scale. As CISA notes, PHP is often embedded in other software and may not be directly visible in asset inventories.
Immediate Actions: Patch and Mitigate
1. Patch PHP (Primary Fix)
Update to the patched versions listed above. This is the only complete fix. Coordinate with your operations teams to schedule emergency patching for internet-facing PHP deployments first.
2. Workaround: Set memory_limit = -1
If you cannot patch immediately, set memory_limit = -1 in php.ini. This prevents zend_bailout() from firing because PHP never hits a memory ceiling. Important: combine this with cgroup v2 memory limits at the container or process level so a runaway PHP process cannot consume all system memory.
; php.ini workaround - combine with cgroup memory limits
memory_limit = -13. WAF Rules
Deploy WAF rules to block multipart requests with excessive file controls or deeply nested parameter names. Cloudflare has published updates to their WAF that block this attack pattern. Check with your WAF vendor for equivalent rules.
4. Reduce Fingerprinting Surface
While not a fix, reducing the information an attacker can gather slows down targeted exploitation:
Set expose_php = Off in php.ini (suppresses the X-Powered-By: PHP/x.x.x header)
Configure Apache with ServerTokens Prod (minimizes the Server header)
Consider stripping server identification headers at your reverse proxy
5. Disable Session Upload Progress (CVE-2026-109619)
If your applications do not use session-based upload progress tracking:
; php.ini - disable if not needed
session.upload_progress.enabled = Off6. Take EOL Systems Offline
As CISA recommends: organizations running PHP 8.1 or earlier (unsupported, no patch available) should take those PHP-based systems offline until they can be upgraded to a supported and patched version.
How Do You Know Your Defenses Actually Work?
Patching is step one. But how do you verify that:
All PHP instances across your infrastructure are actually patched?
Your WAF rules are correctly blocking the attack payload?
Your memory_limit workaround is applied everywhere it needs to be?
Version headers are properly suppressed?
This is where most organizations stop at assumptions. "We pushed the patch, so we should be fine." But in complex environments with dozens or hundreds of PHP endpoints across different teams, configurations drift, patches get missed, and WAF rules have gaps. As CISA points out, PHP is often a component of other software and its prevalence may not be directly observable.
Validating Defenses with Nemesis
At Persistent Security Industries, we built Nemesis specifically for this problem. Nemesis is a Breach and Attack Simulation (BAS) platform that runs real attack techniques against your infrastructure - safely, repeatedly, and automatically - to prove whether your controls stop them.
Within 24 hours of the PHP2Shell disclosure, we developed, tested, and released two production-ready attack simulations:
Simulation 1: Reconnaissance (MITRE ATT&CK T1592.004)
This simulation does exactly what an attacker would do first: fingerprint your web servers to find potentially vulnerable targets.
Sends a standard HTTP GET request (identical to a browser page load - completely non-destructive)
Reads Server, X-Powered-By, and Set-Cookie response headers
Compares detected PHP versions against patched thresholds
Reports whether PHP sessions are active (relevant for CVE-2026-109619)
What the results tell you:
NOT PREVENTED (Exit 0): An attacker can identify this server as running unpatched PHP. Your version headers are exposed and the PHP version is below the patched threshold. Or: PHP sessions are detected but the version is hidden - the server is likely running PHP but the exact version cannot be confirmed remotely (medium confidence).
PREVENTED (Exit 255): The server is either patched, has suppressed version headers with no other PHP indicators, or does not run PHP. An attacker cannot fingerprint it as a PHP2Shell target.
Simulation 2: OOM Exploitation (MITRE ATT&CK T1190)
This simulation sends the actual CVE-2026-109618 attack payload to test whether the vulnerability can be triggered on a given target.
Generates a crafted multipart/form-data payload with configurable parameters (number of controls and nesting depth can be tuned for different memory_limit settings)
Sends it to the target PHP endpoint
Checks whether the server responds with HTTP 500/502/503 (OOM triggered) or a normal response (defended)
What the results tell you:
NOT PREVENTED (Exit 0): The OOM bailout fired. The target is vulnerable. The Use-After-Free condition exists.
PREVENTED (Exit 255): The target handled the payload without crashing. Either it is patched, memory_limit=-1 is in effect, or a WAF blocked the payload before it reached PHP.
Note: The OOM simulation will crash the PHP worker process on a vulnerable target. It is a destructive test by design - you need to know if your servers crash, and the only way to know is to try. Nemesis runs this safely within your authorized test scope.
Real Test Results
We validated both simulations against three configurations to confirm they produce accurate, actionable results:
Configuration | Recon Result | OOM Result | Interpretation |
Unpatched PHP (8.4.24, expose_php=On, memory_limit=128M) | NOT PREVENTED - "PHP 8.4.24 vulnerable, sessions active" | NOT PREVENTED - "HTTP 500" | Both CVEs confirmed exploitable. Patch urgently. |
Workaround applied (expose_php=Off, memory_limit=-1) | NOT PREVENTED - "Sessions active, version hidden" (medium confidence) | PREVENTED - "HTTP 200" | OOM mitigated, but PHP presence detectable. Patch to fully close the gap. |
Non-PHP server (static HTML on Apache) | PREVENTED - "No PHP indicators" | PREVENTED - "HTTP 200" | Not a PHP target. No risk from these CVEs. |
Besides verifying installations are patched, you can use the IOCs created to improve detection rules and verify your response and monitoring efforts are successful.
What Should You Do Right Now?
Inventory your PHP deployments. Follow CISA's guidance: identify all systems running PHP, including those where PHP is a component of other software and may not be directly visible.
Patch immediately. Update to PHP 8.2.35+, 8.3.36+, 8.4.27+, or 8.5.12+. Prioritize internet-facing systems. Take EOL PHP systems (8.1 and earlier) offline.
Apply workarounds where immediate patching is not possible: memory_limit=-1 with cgroup limits, WAF rules, and expose_php=Off.
Validate your defenses. Do not assume patches and WAF rules are working. Run the PHP2Shell simulations in Nemesis to prove it. Our platform tests your actual infrastructure with the actual attack, giving you evidence rather than assumptions.
Monitor and re-test. Set up recurring validation in Nemesis to catch configuration drift, missed patches, and new PHP deployments that appear without protection. Monitor for the suspicious activity indicators CISA describes: PHP worker processes launching shells or downloading tools.
References
CISA Advisory - Critical Vulnerabilities in PHP Require Immediate Patching - October 21, 2026
CVE-2026-109618 - NVD - CVSS 3.1: 9.8, CVSS 4.0: 9.2
CVE-2026-109619 - NVD - CVSS 3.1: 9.8, CVSS 4.0: 9.2
GHSA-w8hw-w9fx-j79w - GitHub Advisory for CVE-2026-109618
GHSA-6wmf-4rv5-p3rp - GitHub Advisory for CVE-2026-109619
Wiz Research - PHP2Shell - Original disclosure
calif.io/php2shell - Technical deep dive
Persistent Security Industries builds Nemesis, a Breach and Attack Simulation platform that validates your security controls with real attack techniques. If you want to test your PHP infrastructure against PHP2Shell or other threats, contact us or visit persistent-security.net.


