October 23, 2026
PHP2Shell | How an AI Uncovered a 10-Year-Old Flaw Threatening 70% of the Web
CVE-2026β109618 & CVE-2026β109619: how memory limits, longjmp(), and stale states allowed unauthenticated Remote Code Execution.

By Thinuri Wickramarachchi
5 min read
CVE-2026β109618 & CVE-2026β109619: how memory limits, longjmp(), and stale states allowed unauthenticated Remote Code Execution.
If you bought something online today, read a blog post, or logged into a customer portal, there is roughly a 70% chance that the code serving your request was written in PHP.
For decades, PHP has been the engine behind major Content Management Systems (CMS) like WordPress, Drupal, and Joomla. But in October 2026, cybersecurity researchers unveiled PHP2Shell a pair of critical, zero-day vulnerabilities (CVE-2026β109618 and CVE-2026β109619) with a CVSS score of 9.2.
What makes PHP2Shell terrifying isn't just that it allows an unauthenticated attacker to execute code on a remote web server. It is how it happens:
- No Authentication Required: An attacker doesn't need a username or password.
- Invisible in Logs: Standard web application logs show a normal
HTTP 200 OK. - Pre-Execution Exploitation: The attack can trigger in memory before your website's security plugins or code ever run.
- AI-Discovered: It was uncovered using AI-assisted source code auditing, finding memory flaws that sat hidden in PHP core for over a decade.
To understand how this works, we need to go back to the basics of how PHP handles memory, errors, and requests.
1. The Setting: How Web Servers Think
Imagine a web server as a restaurant kitchen, and PHP-FPM (FastCGI Process Manager) as a team of cooks (worker processes).
When a visitor loads a page on your website, a request arrives at the kitchen.
- The Request Arrives: A worker process takes the request (e.g., POST form data or file upload).
- Memory Allocation: The cook reserves a cutting board (allocates temporary memory) to parse the incoming data.
- Execution: PHP runs your scripts (WordPress plugins, database calls).
- Cleanup: Once the page is rendered and sent to the visitor, the cook wipes the cutting board clean, resets everything, and waits for the next customer request.
To prevent a single rogue request from consuming the entire server's RAM, PHP enforces a safety guardrail called memory_limit (e.g., 128M). If a single request tries to use more RAM than allowed, PHP panics, throws an Out-Of-Memory (OOM) error, and terminates the request.
2. The Trap: The longjmp() Escape Hatch
How does PHP handle a sudden Out-Of-Memory error?
In lower-level code like C (which PHP itself is written in), when a fatal error or memory shortage occurs, the program cannot just continue. It needs to jump back to a safe recovery point. In C programming, this emergency jump is done using a feature called setjmp() and longjmp().
Think of longjmp() like a teleporter button.
- When PHP starts processing a request, it places a "teleport pad" (
setjmp). - If at any point during request parsing the server runs out of memory, PHP presses the button (
longjmp) and instantly warps execution back to the error handler to clean up and abort.
Here lies the fatal flaw.
Vulnerability #1: CVE-2026β109618 (Uninitialized Cleanup)
When a complex HTTP request comes in (like a large file upload or deeply nested POST form data), PHP initializes internal data structures step by step:
Step 1: Mark structure as "Ready" βStep 2: Allocate Memory βStep 3: Fill with Valid Pointers
If an attacker deliberately crafts a request that forces PHP to hit its memory_limit right between Step 1 and Step 3, PHP triggers a longjmp().
PHP warps instantly to the cleanup phase. The cleanup routine looks at the state, sees "Oh, Step 1 said this data structure is Ready!", and attempts to free memory referenced by pointers in that structure. But because Step 3 never happened, those pointers contain garbage memory addresses or null values.
Trying to read or free garbage memory addresses leads to memory corruption, giving an attacker the ability to manipulate execution flow and gain remote code execution (RCE).
3. The Zombie Worker: Stale State Across Requests
Vulnerability #2: CVE-2026β109619 (Stale Global State)
Web servers recycle worker processes to save computer memory. A single PHP worker process might handle 1,000 requests before restarting.
When an Out-Of-Memory error triggers a longjmp(), PHP aborts the current request. However, because the normal execution flow was abruptly skipped, global variables and pointers pointing to freed memory survive.
When the next innocent customer (or the attacker's second request) arrives at that same worker process:
- The worker process accepts the new request.
- But its internal memory management still holds pointers pointing to memory allocated during the previous failed request (which has now been freed).
- This creates a Use-After-Free (UAF) scenario.
An attacker can deliberately send Request A to corrupt and poison the worker's internal state, and then immediately send Request B to hijack the stale state, overwrite function pointers, and execute arbitrary code on the operating system.
4. The Attack Sequence: Step-by-Step
Let's look at how an attack unfolds in practice:
Why standard security fails to detect it:
- No Application Logs: PHP crashes internally during the engine lifecycle or handles the error via fallback paths before your application (like WordPress) can log an exception.
- Returns HTTP 200: Depending on how web servers like Apache or Nginx communicate with the PHP worker process during certain memory error states, the front-facing web server may log an
HTTP 200 OKresponse while the background worker process is exploited.
5. How It Was Revealed: The AI Auditing Breakthrough
For over 10 years, these memory safety patterns went unnoticed by human auditors because they sit at the intersection of complex C macros, C library error-handling routines (setjmp/longjmp), and PHP's garbage collection.
In mid-2026, researchers leveraged advanced AI models trained on system-level code auditing to analyze the core PHP C source code. The AI was instructed to map every execution path where longjmp() could interrupt memory state initialization.
The AI identified that PHP's request-lifecycle memory guarantees did not hold true during sudden OOM interruptions, leading directly to the discovery of PHP2Shell.
6. How to Protect Your Applications
Because these flaws are inside the PHP core interpreter, application-level fixes (like updating WordPress plugins) will not protect you. You must fix the underlying runtime engine.
1. Upgrade PHP Immediately
The official PHP security team released emergency patches. Update your PHP installation to one of the following safe versions:
- PHP 8.5.12 or higher
- PHP 8.4.27 or higher
- PHP 8.3.36 or higher
- PHP 8.2.35 or higher
(Note: PHP 7.x and 8.1 are End-of-Life (EOL) and do not receive official full upstream releases; legacy systems require OS vendor backports or migrating to supported PHP versions).
2. Mitigation Strategies (If patching is delayed)
If you cannot upgrade immediately, apply these server configuration changes to reduce memory pressure and limit attack vectors:
- Remove finite PHP memory limits for workers (Use with caution): Setting
memory_limit = -1inphp.iniprevents PHP's internal OOM handler from triggering. Warning: You must enforce memory bounds at the OS level (e.g., Linuxcgroup v2or systemd limits) so your server doesn't run out of system RAM. - Reduce Input Pressure:
; Lower maximum POST request size post_max_size = 8M ; Disable session upload progress if unused session.upload_progress.enabled = 0 ; Turn off public error display display_errors = Off- Recycle Workers Frequently: Lower
pm.max_requestsin your PHP-FPM configuration (e.g.,pm.max_requests = 500). This forces worker processes to destroy themselves and restart more often, wiping any stale global state before it can be exploited.
Key Takeaway
PHP2Shell serves as a stark reminder of modern software complexity. Even decades-old, heavily tested open-source engines can harbor memory-safety flaws deep in their low-level runtime lifecycle. As AI tools lower the barrier to discovering these intricate edge cases, maintaining rapid patching and defense-in-depth monitoring (like EDR and OS-level containment) is more critical than ever.