XHack Logo
XHack
Products
Services
Compliance
Pricing
Resources
Company
Sign upLogin
XHack Logo
XHackOffensive Security

Certified offensive security team delivering penetration testing evidence written for your auditor.

OSCP+OSCPC-AI/MLPenCASA
support@xhack.io

24/7 SOC Operations

XHack Status
Under attack? Get help now
Services
  • VAPT Services
  • Red Teaming
  • SOC Services
  • Threat Intelligence
  • Incident Response
  • Managed Testing
Pricing
  • Platform Plans
  • Services Pricing
Compliance
  • SOC 2
  • PCI DSS
  • ISO 27001
  • GDPR
  • HIPAA
  • ISO 42001
  • AI Maturity Assessment
  • TX-RAMP
  • NBFC / SECP
  • All Frameworks
Products
  • Vulnerability Assessment
  • GitGuard
  • AI Probe
  • SOC Dashboard
  • AI Agent
  • Cloud Investigation
Comparison
  • XBOW vs XHack
  • Horizon3 vs XHack
  • Strix vs XHack
  • Pentera vs XHack
Resources
  • Platform Tour
  • All Features
  • Install the Agent
  • XHack AI
  • Documentation
  • Blog
  • Case Studies
  • Documents
  • FAQ
Company
  • About Us
  • Our Team
  • Certifications
  • Security and Trust
  • VAPT Explained
  • Contact

© 2026 XHack. All rights reserved.

Security & TrustVulnerability DisclosurePrivacy PolicyTerms of ServiceRefund Policy
Blog/News

PHP2Shell: Inside CVE-2026-109618 and CVE-2026-109619, the Core PHP RCE That Reaches Back to 2012

XHack

XHack

Author

October 21, 2026

16 min read

PHP2Shell: Inside CVE-2026-109618 and CVE-2026-109619, the Core PHP RCE That Reaches Back to 2012

Table of contents

19

What PHP2Shell Actually Is

The PHP2Shell Mechanism: How CVE-2026-109618 Actually Works

The PHP2Shell Mechanism: How CVE-2026-109619 Actually Works

How the PHP2Shell Chain Actually Produces a Shell

Why PHP2Shell Targets mod_php Specifically, and What That Means for FPM

The Leak, the AI Angle, and Who Gets Credit

How Many Systems PHP2Shell Actually Exposes

Is PHP2Shell Being Exploited Right Now?

Fixing PHP2Shell

Hunting for PHP2Shell Exploitation Attempts

How XHack Reads PHP2Shell

FAQ: PHP2Shell Questions Answered

What is PHP2Shell, exactly?

Is PHP2Shell a WordPress or Drupal vulnerability?

Is there a public exploit for PHP2Shell?

How many systems are affected by PHP2Shell?

Does PHP-FPM protect against PHP2Shell?

What’s the single most effective mitigation if I can’t patch PHP immediately?

The Bottom Line on PHP2Shell

By Salman Khan, OSCP+, Founder of XHack, SRT (Synack Red Team member)

Read this in 30 seconds: PHP2Shell is a pair of unauthenticated remote code execution bugs in the PHP interpreter itself, not a plugin or framework, confirmed working against Apache mod_php with default settings, with code paths researcher Calif traced back to PHP 5.4.0 in 2012. The PHP security team moved its planned October 22 release up a day after the CVE identifiers leaked on October 20, 2026.

  • This is in PHP itself, not a CMS or library. CVE-2026-109618 and CVE-2026-109619 live in how the interpreter handles out-of-memory errors and persistent worker state, so every application running on an affected PHP build is exposed regardless of framework.
  • Both bugs are CVSS 9.2, Critical, confirmed by PHP’s own GitHub security advisories, use-after-free (CWE-416) triggered through request handling any multipart upload can reach.
  • The leak forced an early release. The PHP team had a coordinated October 22 release planned; CVE identifiers circulated publicly on October 20, and the team shipped a day early rather than leave the window open.
  • Researcher Calif confirmed pre-authentication RCE against WordPress, Drupal, Joomla, and Magento, not hypothetical applications, real, widely deployed ones, by chaining the interpreter bug underneath them.
  • Scanning estimates put exposed hosts between 1.3 and 1.9 million, and Cloudflare and watchTowr both report early exploitation attempts within a day of patch release.

Most PHP vulnerabilities live in a plugin, a framework, or a careless include(). The PHP2Shell chain doesn’t. It lives in the interpreter that runs underneath all of them, in code the PHP security team’s own advisory traces to a code path present since PHP 5.4.0, which shipped in March 2012.

What PHP2Shell Actually Is

“PHP2Shell” is the name researchers gave the combined exploit chain; PHP’s own changelog entries don’t use it, referencing instead “avoid state corruption via bailout.” Underneath that name are two separate, officially tracked vulnerabilities, published as GHSA-w8hw-w9fx-j79w and GHSA-6wmf-4rv5-p3rp by the PHP project itself.

CVE-2026-109618CVE-2026-109619
TitleRCE via OOM corruptionRCE via stale global state
CVSS 4.09.2, Critical9.2, Critical
VectorAV:N/AC:H/AT:P/PR:N/UI:N/VC:H/VI:H/VA:HSame
CWEsCWE-416, CWE-755, CWE-824, CWE-1325, CWE-1419Same set
AffectedBelow 8.2.35, 8.3.36, 8.4.27, 8.5.12Same ranges
Patched8.2.35, 8.3.36, 8.4.27, 8.5.12Same

Read the PHP2Shell CVSS vector carefully: AC:H (attack complexity high) and AT:P (attack requirements present) are why this isn’t a trivial one-request bug, but PR:N and UI:N mean no credentials and no victim interaction are needed at all. That combination, hard to pull off reliably, but nothing stopping an unauthenticated attacker from trying, is exactly what the real-world confirmation below bears out.

CVE-2026-109618 and CVE-2026-109619 compared: both CVSS 9.2, both use-after-free, different triggers that chain together
Two bugs, one chain, both confirmed by PHP’s own advisories

The PHP2Shell Mechanism: How CVE-2026-109618 Actually Works

This is the part most PHP2Shell coverage skipped. PHP’s own advisory for CVE-2026-109618 gives the real root cause, and it’s worth walking through because it explains why patching “just” an out-of-memory handler closed a remote code execution hole.

PHP has historically handled out-of-memory errors with longjmp(), a C-level mechanism that immediately unwinds execution back to a safe recovery point, abandoning whatever was running when the allocation failed. That’s normally fine. The problem, per PHP’s own advisory: “in some contexts, request memory is reachable before initialization finishes.” If an allocation fails during that narrow window, before setup has finished tying that memory to cleanup logic, the longjmp() exit skips the accounting entirely. Request memory is left in an invalid, half-initialized state, and nothing downstream knows that happened.

The advisory lists several ways an attacker can deliberately steer a request toward out-of-memory while staying inside PHP’s own configured limits, not by sending a request that’s obviously too large:

  • A multipart upload without a usable declared content length can pass the initial post_max_size check and keep streaming decoded data past it.
  • A single multipart part can carry an unlimited number of headers, each of which consumes far more PHP memory internally than its size on the wire suggests.
  • Empty file upload fields don’t count against max_file_uploads, but still generate file metadata arrays, and nesting field names multiplies that cost.

None of these individually look like a PHP2Shell attack. Together, they’re a way to make PHP run out of memory at a specific, attacker-chosen moment during request startup, which is the trigger the bug actually needs.

The PHP2Shell Mechanism: How CVE-2026-109619 Actually Works

The second PHP2Shell bug is the one that turns a crash primitive into code execution, and it depends on something most PHP deployments assume is safe: long-lived worker processes.

PHP’s advisory describes it as stale global state surviving across requests. A persistent worker, the same PHP process handling request after request, keeps certain global state (error backtraces, session data, object and extension state) that’s supposed to be fully cleared before the next request starts. Normally it is. But a fatal error, including the out-of-memory condition from CVE-2026-109618, can interrupt execution before that cleanup code runs. A non-fatal warning raised during shutdown can even repopulate error state after it was already cleared.

The advisory is explicit about what this needs to actually work: “a producer that leaves request-owned state accessible to a later request, and a consumer that reads, frees, or branches on that state before the next request initializes,” and critically, “the producer and consumer requests must reach the same worker.” That’s why pm.max_requests=1, forcing a fresh worker for every single request, counts as a genuine partial mitigation: it breaks the one precondition this bug can’t work around.

Two confirmed PHP2Shell consumer paths, both from PHP’s own advisory:

  1. PHP 8.5 with fatal_error_backtraces enabled. This feature stores request-owned backtrace state that isn’t reset during shutdown, the basis of the confirmed working RCE against mod_php.
  2. Session upload progress handling. An out-of-memory error during input processing can leave session state “published” in a way a later request on the same worker can read before it’s supposed to exist yet.

How the PHP2Shell Chain Actually Produces a Shell

Put the two PHP2Shell bugs together and the exploit chain researchers demonstrated looks like this, reconstructed from the technical write-ups PHP’s security team validated against:

  1. An attacker sends a multipart upload engineered to push PHP toward out-of-memory during request startup, using one of the header-bloat or empty-field tricks above, while also setting PHP_SESSION_UPLOAD_PROGRESS and a PHPSESSID the attacker controls.
  2. PHP writes a session file to track upload progress. That file gets deserialized by PHP’s own session decoder before any application script runs, and the decoder doesn’t verify the content actually came from PHP itself.
  3. The OOM condition hits during that deserialization. The longjmp() exit from CVE-2026-109618 skips cleanup, leaving stale, half-initialized state behind in the worker.
  4. A second request, on that same worker, triggers another session read. PHP’s internal memory allocator reuses the freed memory from the first request’s incomplete cleanup, and the second decode now runs against memory an attacker partially controls through what it wrote in request one.
  5. The session write-back path eventually calls a method on what the decoder believes is a legitimate object. Because the underlying memory was attacker-influenced, that call can be redirected, and from there, control of the instruction pointer is reachable.

We’re describing the PHP2Shell chain at the mechanism level PHP’s own advisories disclose, which is already substantial, not publishing a working payload. As of the PHP Foundation’s own statement at release time, its security team had reviewed PoC code circulating publicly and “did not identify any functional exploits.” That has very likely changed since; treat the absence of a public one-liner as a currently-true fact, not a permanent one.

The PHP2Shell exploit chain: a producer request leaves stale state, a consumer request on the same worker reuses it, leading to RCE
Producer and consumer requests must land on the same worker

Why PHP2Shell Targets mod_php Specifically, and What That Means for FPM

This matters for PHP2Shell triage, because not every PHP deployment is equally exposed.

Apache’s mod_php is the confirmed case. PHP’s own advisory states mod_php “calls request shutdown even when startup fails,” meaning the invalid state from a failed startup gets processed by shutdown logic before any application code has a chance to run. This is what makes the bug application-independent: it doesn’t matter what your PHP code does, because the exploit fires before it executes.

PHP-FPM is partially protected by its own architecture. FPM terminates the child process entirely when startup fails, which closes off the specific mod_php path. The advisory is careful to note OOM can still occur after normal startup completes, and “no complete FPM exploit has been demonstrated” at time of writing, not “FPM is safe.”

FrankenPHP and LSAPI are flagged as likely affected based on source analysis, per PHP’s advisory, but unvalidated against a working exploit at release time.

The practical PHP2Shell read: if you’re running Apache with mod_php, treat this as confirmed, working, and urgent. If you’re running FPM, you’re not confirmed-exploitable today, but you’re running code with the same underlying bug, and “no demonstrated exploit yet” has a short shelf life on a flaw this widely examined right now.

The Leak, the AI Angle, and Who Gets Credit

The PHP2Shell disclosure timeline is unusual enough to matter for how you prioritize this. PHP’s security team had a coordinated release scheduled for October 22, 2026. On October 20, the CVE identifiers themselves circulated publicly on Hacker News and social media, two days early. Rather than leave a known-leaked, unpatched critical bug sitting for 48 more hours, the PHP team published an advance notice and moved the release to October 21 at 14:00 UTC.

Credit for PHP2Shell is also worth noting, because it’s genuinely unusual: the PHP Foundation credited researcher Calif of Calif.io, Wiz Research, and OpenAI among those involved, and both Calif and Wiz have said publicly that AI models were part of how they found and analyzed this. This isn’t a footnote for this audience specifically. A core-interpreter, decade-plus-old memory-safety bug, surfaced in significant part through AI-assisted research, is close to exactly the kind of finding the AI security research community has spent the past two years warning would eventually show up at this scale.

How Many Systems PHP2Shell Actually Exposes

Two independent scanning estimates for PHP2Shell’s real-world exposure circulated within a day of the patch: researcher Silas Cutler put exposed, internet-facing hosts at roughly 1.3 million, and a separate Shodan-based count from Henk Poley came in over 1.9 million. Neither is an authoritative census, scanning estimates always undercount what’s not directly fingerprintable, but both point the same direction: this is a large-scale, internet-wide exposure, not a niche one.

Calif’s own research reportedly confirmed pre-authentication RCE against WordPress, Drupal, Joomla, and Magento specifically, not as a theoretical “any PHP app could be affected” claim, but as tested, working chains against four of the most widely deployed PHP-based platforms on the internet.

Scanning estimates put PHP2Shell's internet-facing exposure between 1.3 and 1.9 million hosts, with confirmed pre-auth RCE against four major PHP platforms
1.3 to 1.9 million hosts, by two independent scans

Is PHP2Shell Being Exploited Right Now?

The honest answer depends on whose telemetry you’re reading, and the sources genuinely disagree in timing, which is worth stating plainly rather than picking the scarier one.

Cloudflare reports “early attacks emerging” and has already shipped WAF rules for known exploit vectors to all customers, including free tier, explicitly calling it a stopgap that only covers traffic routed through Cloudflare’s network.

watchTowr says it independently reproduced both bugs and is observing exploitation attempts in its own monitoring.

Huntress, as of October 21 at 10am ET, said it had not yet observed in-the-wild exploitation across its own partner telemetry, while noting other researchers were reporting attacks it couldn’t independently verify from where it sat. Huntress also published a now-removed short exploitation demonstration video reference, and set up Sigma/YARA rule publication for once more technical detail becomes available.

Read that as: exploitation had very likely started somewhere within 24 hours of patch release, but it had not yet reached blanket, opportunistic, internet-wide scanning levels that every telemetry source would independently confirm at the same moment. That gap closes fast on a bug this exposed.

Fixing PHP2Shell

BranchAffectedFixed
8.5.xBefore 8.5.128.5.12
8.4.xBefore 8.4.278.4.27
8.3.xBefore 8.3.368.3.36
8.2.xBefore 8.2.358.2.35
7.4 through 8.1AffectedNo official release; the PHP security team published minimal source backports
5.4 through 7.3Affected, end-of-lifeNo fix from the PHP project at all

If you’re on an end-of-life branch affected by PHP2Shell, upgrading PHP itself, not just applying a backport, is the only path to a fully supported fix. A source backport closes the specific hole without the years of other unpatched issues an EOL branch has accumulated.

If you cannot update immediately, PHP’s own advisories list these as partial, not complete, mitigations:

  1. Set memory_limit=-1 in a way applications cannot override, specifically for CVE-2026-109618. The advisory is explicit this is not a full fix, and removes a resource-exhaustion protection you may actually need.
  2. Set session.upload_progress.enabled=0 if the feature isn’t in active use, closing the confirmed session-based consumer path for CVE-2026-109619.
  3. On PHP 8.5 specifically, set fatal_error_backtraces=0, closing the other confirmed consumer path.
  4. Keep post_max_size conservative and enforce request size limits at your frontend or reverse proxy, reducing the OOM-triggering surface.
  5. Set pm.max_requests=1 on FPM if your performance budget allows it, breaking the same-worker requirement CVE-2026-109619 needs.
  6. Restart every PHP worker process after making any of these changes. Stale workers keep the old configuration and the old in-memory state.

A container or cgroup memory limit can bound the PHP2Shell availability impact of a crash loop, but CERT-EU’s own guidance goes further: isolate internet-facing applications from public networks entirely until a verified fix is applied, if you can’t patch on an urgent timeline.

Hunting for PHP2Shell Exploitation Attempts

Huntress’s published guidance, pending full Sigma/YARA rules, centers on watching what a PHP worker process spawns, since a successful exploit executes code with the worker’s own privileges:

  • Suspicious child processes launched by php-fpm, php-cgi, httpd, or apache2: shells (sh, bash, cmd.exe, powershell.exe), interpreters (python, perl), or download/network tools (curl, wget, nc, certutil.exe).
  • Command-line patterns consistent with reverse shells or pivoting: /dev/tcp/, fsockopen, mkfifo.
  • Basic reconnaissance commands run from the web server context: whoami, id, uname -a, ipconfig.
# Illustrative starting point for log review, adapt to your own log pipeline.
# Looks for PHP worker processes spawning an unexpected shell or interpreter.
grep -E "(php-fpm|php-cgi|apache2|httpd).*(sh -c|bash -c|/bin/sh|wget |curl .*\|)" \
  access.log error.log 2>/dev/null

If you find evidence of compromise, isolate the server, preserve PHP and web server logs before taking further action, and check for new webshells in the web root, new cron jobs, scheduled tasks, or accounts, the same forensic discipline any confirmed RCE deserves.

How XHack Reads PHP2Shell

So this is where we talk about our own angle, clearly marked as that.

What makes the PHP2Shell chain worth more than a routine patch-now notice is exactly what the research credits show: AI-assisted analysis surfacing a decade-old, interpreter-level memory bug that manual review had missed for years. That’s the direction offensive AI research is actually heading, and it’s a large part of what our own AI exploit development coverage and agent capabilities are built around: systematic, exhaustive analysis of exactly the kind of edge-case state-management bug a human reviewer skims past.

A pentest report tells you what was tested and found. It doesn’t replace applying PHP’s own patch, and it doesn’t substitute for the forensic steps above if you have reason to suspect you were hit before you patched. XHack doesn’t store your data; your session data stays on your own machine.

FAQ: PHP2Shell Questions Answered

What is PHP2Shell, exactly?

PHP2Shell is the researcher-given name for an exploit chain combining CVE-2026-109618 and CVE-2026-109619, two critical, CVSS 9.2 vulnerabilities in the PHP interpreter itself. Together they allow unauthenticated remote code execution, confirmed working against Apache mod_php, and PHP’s own security team traces the affected code path to PHP 5.4.0, released in 2012.

Is PHP2Shell a WordPress or Drupal vulnerability?

No, it’s in the PHP interpreter underneath them. Researcher Calif confirmed the chain produces working pre-authentication RCE against WordPress, Drupal, Joomla, and Magento specifically, but the root cause has nothing to do with any of those platforms’ own code; any application running an affected PHP build is exposed.

Is there a public exploit for PHP2Shell?

Code claiming to exploit it circulated publicly after the CVE identifiers leaked on October 20, 2026. The PHP Foundation’s own security team reviewed available PoCs at release time and said it did not identify any functional exploits at that point, though researchers including watchTowr say they independently reproduced both bugs.

How many systems are affected by PHP2Shell?

Independent scanning estimates range from roughly 1.3 million (Silas Cutler) to over 1.9 million (Henk Poley, via Shodan) internet-facing hosts. Every PHP version from 5.4 through 8.5.11 is affected; only 8.2.35, 8.3.36, 8.4.27, and 8.5.12 are patched.

Does PHP-FPM protect against PHP2Shell?

Partially, by architecture rather than by design against this specific bug. FPM terminates a worker entirely when startup fails, closing the confirmed mod_php attack path. PHP’s own advisory notes OOM can still occur after normal startup on FPM, and states no complete FPM exploit has been publicly demonstrated, which is different from FPM being confirmed safe.

What’s the single most effective mitigation if I can’t patch PHP immediately?

There isn’t one single fix short of updating. The closest combination is disabling session.upload_progress, setting fatal_error_backtraces=0 on PHP 8.5, and setting pm.max_requests=1 on FPM to break the same-worker requirement CVE-2026-109619 needs, restarting all workers afterward. PHP’s own advisory calls updating “the only reliable mitigation.”

The Bottom Line on PHP2Shell

PHP2Shell is a rare thing: a confirmed, working, unauthenticated remote code execution chain in the language runtime itself, not a framework or plugin, exposed on well over a million internet-facing hosts, and traceable to code that shipped before most current PHP developers started their careers. The leak that forced PHP’s hand turned a planned, coordinated release into an emergency one, and real PHP2Shell exploitation attempts were already starting within a day.

If you run PHP in any capacity, especially Apache with mod_php, treat PHP2Shell as urgent, not routine. Patch to 8.2.35, 8.3.36, 8.4.27, or 8.5.12, apply the interim mitigations above if you genuinely can’t patch today, and watch your logs for the process-spawn patterns a successful exploit leaves behind.


Categories

News

Next

Bug Bounty Report Writing: What Actually Gets You Triaged Fast

On this page

What PHP2Shell Actually Is

The PHP2Shell Mechanism: How CVE-2026-109618 Actually Works

The PHP2Shell Mechanism: How CVE-2026-109619 Actually Works

How the PHP2Shell Chain Actually Produces a Shell

Why PHP2Shell Targets mod_php Specifically, and What That Means for FPM

The Leak, the AI Angle, and Who Gets Credit

How Many Systems PHP2Shell Actually Exposes

Is PHP2Shell Being Exploited Right Now?

Fixing PHP2Shell

Hunting for PHP2Shell Exploitation Attempts

How XHack Reads PHP2Shell

FAQ: PHP2Shell Questions Answered

What is PHP2Shell, exactly?

Is PHP2Shell a WordPress or Drupal vulnerability?

Is there a public exploit for PHP2Shell?

How many systems are affected by PHP2Shell?

Does PHP-FPM protect against PHP2Shell?

What’s the single most effective mitigation if I can’t patch PHP immediately?

The Bottom Line on PHP2Shell

Related articles

Continue reading

CVE-2026-0322: Why “Authenticated” Doesn’t Mean Low-Risk on a PAN-OS Firewall

News

CVE-2026-0322: Why “Authenticated” Doesn’t Mean Low-Risk on a PAN-OS Firewall

CVE-2026-0322 is a root-level PAN-OS RCE, actively exploited, scored 7.2 by NVD and 8.6 by Palo Alto. Why PR:High is sca...

Read article
CVE-2026-105134: The Ahsay Backup Server Patch That Took Three Tries

News

CVE-2026-105134: The Ahsay Backup Server Patch That Took Three Tries

CVE-2026-105134 is a perfect-10.0 Ahsay backup server RCE, chainable with CVE-2026-105133. Ahsay’s own patch faile...

Read article
CVE-2026-76519: Cisco’s Second Critical Email Gateway Zero-Day in a Month

News

CVE-2026-76519: Cisco’s Second Critical Email Gateway Zero-Day in a Month

CVE-2026-76519 lets an unauthenticated attacker get root via a crafted email attachment on Cisco Secure Email Gateway. F...

Read article