scrolltotop

new Get your brand recommended by ChatGPT, Perplexity & AI search engines. Discover GEO.

new We help companies keep track of engineering health with monthly reports. Start your review today.

PHP2Shell: Critical PHP RCE Vulnerabilities Explained

Home Company Blog PHP2Shell: Critical PHP RCE Vulnerabilities Explained
PHP2Shell: Critical PHP RCE Vulnerabilities Explained

Patches are now available. PHP 8.5.12, 8.4.27, 8.3.36, and 8.2.35 fix both PHP2Shell vulnerabilities, and the PHP Security Team has confirmed unauthenticated remote code execution. Update immediately. See our update on the official patches for affected environments and interim mitigations.

On October 20, the PHP Security Team did something unusual: it warned developers about two critical vulnerabilities before releasing the patches or even disclosing the technical details.

The official announcement confirmed two vulnerabilities, both rated 9.2 under CVSS v4.0, and scheduled an emergency security release for October 21 at 14:00 UTC. The team also reserved the right to release the fixes earlier if exploit details became public or active exploitation was detected.

The vulnerabilities, identified as CVE-2026-109618 and CVE-2026-109619, are already being discussed under the name PHP2Shell.

According to CERT-EU, early reports suggest the possibility of unauthenticated remote code execution (RCE), with potential exposure extending back to PHP 5. At that point, the official list of affected versions and exploitation requirements hadn't been published.

That distinction mattered. The severity was confirmed early, but until the advisories were published, much of what we knew about the underlying vulnerabilities came from independent security research.

With PHP powering applications across Laravel, Symfony, WordPress, Drupal, and many other platforms, there's good reason for developers and infrastructure teams to pay attention.

What might actually be happening inside PHP?

Editor's note: Subsequent research has challenged the original cached-pointer use-after-free explanation. See our updated technical findings below. The stale global state vulnerability later confirmed by the PHP Security Team (CVE-2026-109619) shouldn't be read as the same mechanism described in this section. See our update on the official advisories.

One of the more detailed early investigations comes from Upwind's technical assessment.

Their analysis points to a possible use-after-free vulnerability in PHP's session upload progress handling, specifically in php_session_rfc1867_callback() within ext/session/session.c.

PHP has a built-in mechanism for tracking file upload progress through sessions. During multipart HTTP request processing, it maintains information about incoming uploads, including how many bytes have been received.

According to Upwind, certain request sequences may cause PHP to retain references to memory that has already been released. If an attacker can manipulate how that memory is reused, the result could potentially be arbitrary code execution.

The researchers also suggest that the issue may be exploitable with default PHP configurations, particularly because session.upload_progress.enabled is enabled by default.

If confirmed, this would be significant for one particular reason: the vulnerable behavior could occur during PHP's request processing, before application-level code has an opportunity to handle the request.

That means a perfectly maintained Laravel application, with updated dependencies and properly implemented authentication, could still be exposed through its PHP runtime.

It's important not to confuse this with a framework vulnerability. Laravel, Symfony, and WordPress aren't necessarily responsible for the underlying issue, and updating application dependencies alone wouldn't address a vulnerability inside PHP itself.

The PHP Security Team has since published the actual root causes, which we cover in our update on the official patches.

Independent researchers are already publishing PoCs

Before the official disclosure, independent researchers had already started publishing technical analyses and proof-of-concept code.

One interesting example is Qi Deng's php2shell-poc repository, published on October 21.

The repository documents three possible attack chains involving PHP session handling:

  1. Session file injection combined with LFI: Manipulating session data through upload progress handling, then exploiting an application-level local file inclusion vulnerability to execute the injected content.
  2. Use-after-free during deserialization: Exploring memory corruption involving unserialize(), object destructors, and PHP's internal memory management.
  3. Session serializer mismatch: Investigating situations where different session serialization configurations could lead to unexpected object deserialization and potentially dangerous destructor execution.

The researcher claims successful RCE demonstrations for these chains and provides verification scripts, a Docker laboratory, and a technical write-up.

However, there's an important distinction between what the repository claims and what its published test scripts independently establish.

The session injection scenario requires an additional LFI vulnerability. The use-after-free script focuses on demonstrating memory behavior under AddressSanitizer rather than providing a complete remote exploit. The serializer mismatch scenario also depends on particular configuration conditions and an exploitable object or gadget chain.

In other words, the existence of these PoCs doesn't establish that every default PHP installation is vulnerable to unauthenticated RCE through all three methods. Nor has the precise relationship between these chains and the two announced CVEs been officially confirmed.

Another interesting detail is an earlier PHP source code pull request, #22113, originally opened in May 2026. It addresses how PHP's multipart upload progress handler accepts session identifiers from form data even when session.use_only_cookies is enabled.

The PR predates the current disclosure by several months and touches an area now attracting considerable attention. That makes it worth examining, although there's currently no confirmation that it directly fixes either of the new vulnerabilities.

Taken together, these investigations suggest PHP's session handling deserves close attention. But we should be careful not to treat separate research findings as a single, fully verified exploit chain.

How Laravel is responding

The Laravel team has already confirmed that it's working directly with the PHP Foundation and coordinating security updates across Laravel Cloud, Forge, and Vapor.

For Laravel Forge, the plan announced ahead of the release was for customers to apply the patched PHP versions to their servers. The team contacted Forge users and promised further guidance once the releases were published.

Laravel Vapor's PHP runtime layers were also expected to receive updates.

This is an important distinction for teams running Laravel in production. Framework security, dependency management, and runtime security are related, but they're not interchangeable.

Running composer update won't patch PHP itself. Likewise, putting a Laravel application into maintenance mode shouldn't be treated as protection against vulnerabilities that may be triggered before Laravel processes the request.

The good news is that the Laravel team is coordinating directly with the people responsible for the runtime, which should help hosting and application teams respond more quickly once the fixes are available.

Cloudflare confirms attacks are already emerging

Perhaps the most important development so far came from Cloudflare CTO Dane Knecht.

In an October 21 post on X, Knecht confirmed that Cloudflare had already deployed an initial set of WAF rules targeting known exploitation vectors for these vulnerabilities.

The protection is available to all Cloudflare customers, including those on the free plan.

More importantly, he confirmed that Cloudflare is already observing early attacks and updating mitigations as new exploitation methods emerge.

That changes the urgency of the situation. We're no longer dealing exclusively with hypothetical attack scenarios. There is already suspicious traffic associated with these vulnerabilities, although observing attack attempts doesn't necessarily mean successful server compromises have occurred.

Cloudflare's emergency Managed Ruleset update introduces four new anomalous execution detections. Two are configured to block matching requests, while the other two initially operate in logging mode.

A separate update for free customers provides two blocking rules.

Knecht also warned paid customers to verify that their WAF is enabled and that relevant rules haven't been configured to operate only in log mode.

An interesting exchange followed his announcement. Someone proposed a more aggressive emergency protection option that could temporarily block POST requests, form submissions, sessions, or file uploads altogether.

Knecht replied that Cloudflare was considering the idea.

It's an understandable suggestion in a situation where protecting the application might temporarily require restricting functionality. But such measures would come with significant operational trade-offs.

Knecht was also explicit about the limitations of Cloudflare's response: WAF rules are a stopgap, not a replacement for patching PHP.

What this means for production environments

At Moneo, PHP and Laravel are a significant part of the applications and infrastructure we build and maintain for our clients.

Our main concern in situations like this isn't whether a particular language or framework is secure in general. Vulnerabilities are a reality across programming languages, runtimes, operating systems, and infrastructure platforms.

The important question is how quickly we can understand the exposure and respond without unnecessarily disrupting production systems.

For teams operating PHP applications, there are a few immediate priorities:

  • Identify the PHP versions actually running in production. That includes PHP-FPM processes, containers, virtual machines, and separate runtime environments. The CLI version reported by php -v may not be the version serving web requests.
  • Review session upload progress configuration. Disabling session.upload_progress.enabled may reduce exposure to the suspected attack path if the application doesn't require it. This hasn't been confirmed as a complete mitigation for both vulnerabilities. The PHP Security Team has since published separate interim mitigations for each CVE. Disabling upload progress addresses only some CVE-2026-109619 paths. See What should you do now?
  • Verify WAF protection and origin access. Cloudflare's emergency protections are useful, but they won't help if an attacker can bypass Cloudflare and reach the origin server directly.
  • Watch for unusual activity. Unexpected PHP-FPM worker crashes, unusual multipart requests, and unexplained HTTP 5xx responses deserve investigation. None of these alone proves exploitation.
  • Deploy the official patches. PHP 8.5.12, 8.4.27, 8.3.36, and 8.2.35 are now available. Prioritize internet-facing services, verify the fixed runtime is actually in use after deployment, and plan upgrades for unsupported PHP versions that may not receive security fixes.

One more concern is what happens now that the patches are published.

Attackers can compare vulnerable and patched source code to better understand the underlying defects. This is a normal part of security research, but it also means that systems left unpatched may become easier to target as technical details spread.

That's why identifying the affected runtime and having a reliable deployment process matter just as much as understanding the exploit itself.

What happens next?

The PHP Security Team released the fixes on October 21: PHP 8.5.12, 8.4.27, 8.3.36, and 8.2.35. The official advisories confirmed unauthenticated remote code execution and explained the root causes of both vulnerabilities. We cover the details in our update on the official patches.

What we knew before the release was already enough to justify preparation: two critical vulnerabilities rated 9.2, preliminary research pointing toward remote code execution, independent PoCs appearing publicly, and Cloudflare confirming that early attacks were being observed. The official advisories have since confirmed that urgency.

It's also worth recognizing how quickly the ecosystem is responding. The PHP Foundation, Laravel, Cloudflare, and independent security researchers have all contributed different pieces of the response, from coordinated disclosure and runtime fixes to edge protection and technical analysis.

For us, the takeaway is straightforward.

Application security doesn't end with application code. The runtime, web server, network configuration, dependencies, and deployment process are all part of the same system.

The patches and full advisories are now published. The sensible approach hasn't changed: distinguish confirmed facts from early research, understand where PHP is running, and update.

That's far more useful than speculation, and ultimately what matters most for keeping production systems secure.


Update: New Research Challenges Early PHP2Shell Exploit Claims

Note: The findings below apply to the specific public PoCs and early explanations we reviewed. They don't contradict the PHP Security Team's later confirmation of unauthenticated RCE. See our update on the official patches.

Following our initial analysis, we reviewed three additional resources: J4ck3LSyN's investigation, the Zer061 repository, and another publicly available PoC.

The most interesting development isn't a new exploit, but a correction to an earlier one.

J4ck3LSyN revisited the original cached-pointer use-after-free theory and found that PHP's Z_TRY_ADDREF(progress->data) keeps the referenced array alive, invalidating that specific exploit chain. The researcher subsequently reported a different potential use-after-free issue involving serialization state, reproduced under specific conditions using AddressSanitizer. However, remote code execution has not been demonstrated through this alternative mechanism.

We also compared the two GitHub repositories and found that their PoC implementations share substantially similar code and assumptions. Neither provides independent confirmation of the original RCE claims. We also wouldn't recommend deploying the unofficial PHP source patch included in the eness repository in production.

This doesn't invalidate the critical vulnerabilities announced by the PHP Security Team. It means some early exploit explanations haven't held up to further scrutiny. The relationship between these research findings and the two announced CVEs also remains unconfirmed.

Our recommendation remains unchanged: review your PHP runtime exposure, verify WAF protections, and prioritize official security patches.

We'll continue updating our analysis as more verified technical details become available.


Update: Official PHP Security Patches Are Now Available

The PHP Security Team has officially released fixes for both PHP2Shell vulnerabilities. PHP 8.5.12, 8.4.27, 8.3.36, and 8.2.35 are now available, and all affected installations should be updated immediately.

The official advisories also clarify the actual root causes, replacing much of the speculation surrounding the early PoCs.

CVE-2026-109618: RCE via OOM corruption

PHP's out-of-memory handling could interrupt request processing while internal data was only partially initialized. During cleanup, PHP could then process this invalid state, potentially allowing arbitrary code execution.

The PHP team confirmed unauthenticated RCE against Apache mod_php, triggered before application code executes. PHP-FPM, php-cgi, FrankenPHP, and LiteSpeed are also within scope. No complete PHP-FPM exploit has been demonstrated for this CVE, but the advisory's source analysis suggests FPM is still susceptible.

CVE-2026-109619: RCE via stale global state

Request-owned internal state could survive after its backing memory was freed. Subsequent requests handled by the same worker could access that stale state, resulting in a use-after-free vulnerability.

The official advisory confirms RCE through demonstrated paths involving mod_php and PHP-FPM, including session upload progress handling.

These findings also clarify our earlier research update: while some publicly circulating PoCs relied on incorrect assumptions, the underlying critical vulnerabilities and their RCE impact are now officially confirmed.

How the vulnerabilities were found

OpenAI has also published its account of the disclosure. According to OpenAI, Calif identified one of the flaws using GPT-5.6 Sol as part of OpenAI's Patch the Planet initiative, and Wiz independently discovered and reported both vulnerabilities. The PHP maintainers led the fixes and the release, with OpenAI, Wiz, Cloudflare, and other partners contributing research, coordination, and protections ahead of disclosure.

OpenAI expects AI-assisted findings like these to increase sharply in the coming months, and notes that the same capabilities can help attackers develop exploits faster. For teams running PHP in production, that reinforces a point we made earlier: knowing where your runtimes are running, and being able to update them quickly, matters as much as understanding any single vulnerability.

What should you do now?

Update PHP immediately. There is no complete configuration-based mitigation for either vulnerability.

If immediate patching isn't possible, the PHP Security Team recommends temporary measures for specific attack paths:

  • For CVE-2026-109618, enforcing memory_limit=-1 in a way applications can't override (for example, php_admin_value in the FPM pool or Apache config) and restricting request sizes at the web server or proxy can reduce exposure. If you need a memory cap, use container or cgroup limits rather than RLIMIT_AS or RLIMIT_DATA, which can trigger the vulnerable path. This carries resource-exhaustion risks and is not a complete fix.
  • For CVE-2026-109619, disabling session.upload_progress.enabled and restarting all workers blocks confirmed session-related paths. PHP 8.5 installations can also disable fatal_error_backtraces to mitigate a separate confirmed path.
  • Ensure updated PHP-FPM, Apache, container, and other long-running PHP processes actually use the patched runtime.

PHP 8.1 and older versions no longer receive standard security releases from the PHP project, although vendor backports and limited source patches are available for some older branches.

The official advisory is clear: temporary mitigations reduce exposure, but updating PHP is the only complete solution.

We strongly recommend prioritizing this update across all production environments.

Moneo as Your Enterprise Partner

We collaborate closely with enterprise teams to design, deliver, and operate systems built for the long run.

Start Partnership
Emir Karşıyakalı

Emir Karşıyakalı

Founder & CEO

Jump to

Moneo as Your Enterprise Partner

We collaborate closely with enterprise teams to design, deliver, and operate systems built for the long run.

Start Partnership
Partnership is at the core of what we do.

Unsure where to start?
Let's figure it out together 👋

Contact Us