Award ZeroThreat Wins Bronze Stevie® Award in Tech Startup of the Year Read more
leftArrow

All Blogs

Vulnerability

PHP2Shell (CVE-2026-109618 and CVE-2026-109619): How the Unauthenticated PHP RCE Works and How to Fix It

Published Date: Oct 23, 2026
PHP2Shell Explained: PHP RCE Risks, Fixes & Detection

Quick Overview: PHP2Shell is the name for CVE-2026-109618 and CVE-2026-109619, two critical flaws in the PHP runtime that can give an unauthenticated attacker code execution on any server running PHP for the web. PHP 8.5.12, 8.4.27, 8.3.36 and 8.2.35 fix both. Patch now.

PHP2Shell is the name for CVE-2026-109618 and CVE-2026-109619, two critical flaws in the PHP runtime that can give an unauthenticated attacker code execution on any server running PHP for the web. PHP 8.5.12, 8.4.27, 8.3.36 and 8.2.35 fix both. Patch now.

Most PHP compromises start with a bug in the application: a vulnerable plugin, an unsafe upload handler, a forgotten admin route. PHP2Shell skips that step. The flaws live in the PHP runtime itself, so an attacker does not need a weakness in your code, a login, or even a valid route. On Apache with mod_php, the PHP security advisory describes a demonstrated exploit where a single unauthenticated request triggers the attack before any application code runs.

The timing makes it worse. Details leaked before the coordinated release. Cloudflare saw attack traffic aimed at its customers, and Amazon's honeypots recorded an exploitation attempt four days before the CVEs were public. Defenders started this race from behind.

This guide breaks down how the two bugs work, which deployments carry the most risk, what each stopgap actually blocks, and how to prove the fix is running rather than merely installed.

On This Page
  1. What is PHP2Shell?
  2. How PHP2Shell Works
  3. Which PHP Deployments Are at Risk?
  4. Fixed Versions and How to Patch
  5. Temporary Mitigations If You Cannot Patch Yet
  6. How to Verify the Fix and Check for Compromise
  7. How ZeroThreat Detects and Helps Remediate PHP2Shell
  8. Key Takeaways
  9. Conclusion

What is PHP2Shell?

PHP2Shell is the collective name for CVE-2026-109618 and CVE-2026-109619, two memory-safety flaws in the PHP runtime that can let an unauthenticated attacker execute code on a server through ordinary HTTP requests. The PHP security team rates both at 9.2 on CVSS v4.0.

Calif.io, Wiz, OpenAI and Quarkslab disclosed the bugs. Because they sit in PHP's core request handling rather than in a framework or extension, every application built on top inherits the exposure, from WordPress and Laravel to Magento and custom code.

Date (2026)Event
Oct 17Amazon's MadPot honeypot network records a PHP2Shell exploitation attempt
Oct 20PHP announces an emergency security release after details leak
Oct 21Cloudflare deploys WAF rules roughly nine hours ahead of public disclosure
Oct 21, 14:00 UTCPHP ships 8.5.12, 8.4.27, 8.3.36 and 8.2.35; CISA issues an alert urging immediate patching

How PHP2Shell Works

PHP2Shell works by getting PHP to trust internal request state that is not what PHP believes it is: half-built data in one flaw, already-freed data in the other. Both routes end in memory corruption that researchers turned into remote code execution, and a related technique leaks worker memory without any login.

CVE-2026-109618: Out-of-Memory Corruption

When PHP runs out of memory partway through handling a request, it can be interrupted while internal request data is only partly initialized (GHSA-w8hw-w9fx-j79w). The cleanup code that runs afterwards treats that half-built data as valid, which hands an attacker a corrupted structure to work with.

From the attacker's side, the important detail is control over where the failure lands. PHP's memory limit is a fixed, configured ceiling, and request parsing allocates memory in proportion to what the client sends. Large bodies, many input variables, deep nesting and multipart uploads all drive allocation during parsing, before your application sees anything. That is why PHP's interim guidance targets post_max_size, input nesting and multipart limits.

CVE-2026-109619: Stale Global State

Here, request-owned internal state can outlive the memory backing it (GHSA-6wmf-4rv5-p3rp). A later request served by the same worker can touch that freed memory before PHP's normal initialization resets it: a use-after-free that spans two requests.

This is a persistent-worker problem. mod_php and PHP-FPM reuse the same process for many requests, so an attacker can send one request to leave dangling state behind and a follow-up that lands on the same worker to use it. PHP has confirmed reachable paths through session upload-progress handling, fatal-error backtraces on PHP 8.5, diagnostics emitted before initialization, and attacker-triggerable fatal errors and timeouts.

Leaking Worker Memory Without Logging In

Researchers also demonstrated unauthenticated disclosure of PHP worker memory. A worker's heap can hold database passwords, session tokens and API keys from earlier requests. An attempt that never reaches code execution can still be a data breach, which changes how you scope incident response for any server that was exposed before patching.

Which PHP Deployments Are at Risk?

PHP2Shell affects every PHP installation that serves web requests, regardless of application or framework, and Apache mod_php carries the highest risk. The difference between deployments comes down to how PHP is attached to the web server and how long its workers live.

DeploymentExposureWhy
Apache mod_phpHighestDemonstrated unauthenticated exploit that fires before any application code runs
PHP-FPMAffectedStartup behavior blocks one out-of-memory path, but PHP validated RCE through the session lifecycle under suitable application conditions
php-cgiAffectedNamed by PHP as an at-risk installation type
FrankenPHPAffectedNamed by PHP as an at-risk installation type
LiteSpeedAffectedNamed by PHP as an at-risk installation type

The version range is wide. Cloudflare describes the flaws as affecting web servers running PHP 5.4 or later, yet only branches 8.2 through 8.5 receive official fixed releases. Long-lived estates on PHP 7.x and 8.0 are therefore exposed with no packaged upstream fix.

PHP also notes that exploitability varies with configuration and application behavior. That cuts both ways: a server that looks protected on paper may still be reachable through a path nobody listed, so exposure is something to test from the outside, not assume.

Fixed Versions and How to Patch

The only complete fix for PHP2Shell is a PHP build that includes the October 21, 2026 patches: 8.5.12, 8.4.27, 8.3.36, 8.2.35, or a vendor package with the fixes backported.

PHP branchFixed release
8.58.5.12
8.48.4.27
8.38.3.36
8.28.2.35Reaches end of life on December 31, 2026; plan the next upgrade now
8.1, 8.0, 7.4No official releaseMinimal source backports from the PHP security team; otherwise use an LTS vendor or upgrade
OlderNoneUpgrade to a supported branch

Three traps catch teams during rollout:

  • Backported version strings. Distribution packages often carry the fix under an older upstream version number. Check the full package version against your vendor's advisory, not against the table above.
  • Third-party repositories. PHP warned that the volunteer-run rpms.remirepo.net would not have updates on release day and urged users to switch to distribution packages or build from source.
  • Windows. Fixed Windows source and binaries are published on the php.net downloads page alongside the source releases.

Temporary Mitigations If You Cannot Patch Yet

No configuration change makes an unpatched PHP installation safe; each of PHP's stopgaps closes a specific attack path and leaves others open. Apply them only to buy time, and apply them at the server or pool level, because ini_set() and FPM .user.ini files take effect too late to protect request parsing.

StopgapWhat it blocksWhat it leaves open
memory_limit=-1 via php_admin_valueAttacker-controlled failures at PHP's configured memory ceiling (CVE-2026-109618)Genuine allocation failures still reach the bug; removing the cap invites resource exhaustion
post_max_size of 8M (32M if uploads are needed), upload_max_filesize below itShrinks how much allocation a request can forceNot a block, only a smaller lever
Proxy or web-server limits on decoded size, field count, multipart parts, headers and nestingParsing pressure before PHP sees the requestMust also cover requests without a usable Content-Length; block multipart entirely if unused
Container or cgroup memory limits that kill only the affected workerAvailability impactDo not use RLIMIT_AS or RLIMIT_DATA, which can trigger the vulnerable failure
session.upload_progress.enabled=0Confirmed session paths (CVE-2026-109619)Other stale-state variants
fatal_error_backtraces=0 on PHP 8.5Confirmed fatal-backtrace pathOnly that path
Remove invalid per-request settings; fix attacker-triggerable fatal errors and timeoutsDiagnostic and error paths that touch stale stateHiding errors with @ or display_errors does nothing
pm.max_requests=1 on PHP-FPMReuse of a worker across requestsSignificant performance cost

Restart every worker after each change and confirm that no pool, directory or application setting quietly restores the old value.

A WAF is a useful layer here, not a substitute. Cloudflare shipped managed rules before disclosure and then watched attackers mutate payloads to slip past them. If a patched build cannot go out promptly, restrict public access to the service or isolate it, and give each waiting system an owner and a deadline.

How to Verify the Fix and Check for Compromise

A PHP2Shell fix is complete only when every process serving web traffic runs a patched build, which means checking the running runtime rather than the package manager.

  • Find every PHP install. Include parallel branches, container images, hosting-panel bundles and PHP shipped inside appliances. The version that php -v reports belongs to the CLI binary, which may not be the module or FPM pool serving requests.
  • Update the right artifact. For containers, a patched base image changes nothing until the application image is rebuilt and redeployed.
  • Restart or replace workers. Long-lived workers keep running the old build until they are recycled. Confirm that none are left.
  • Roll back emergency settings. Once the patched runtime is confirmed, restore a finite memory_limit and revisit temporary upload limits and worker recycling.
  • Assume an exposure window. For internet-facing servers unpatched since mid-October, rotate secrets that live in PHP worker memory, such as database credentials, API keys and session signing keys, and hunt for web shells and PHP or web-server workers spawning shell processes. No public indicators of compromise had been released at the time of writing.

Finally, retest from the outside. A server is fixed when an attacker-position test can no longer reach the flaw, not when a ticket says the package was updated.

How ZeroThreat Detects and Helps Remediate PHP2Shell

ZeroThreat detects PHP2Shell exposure with a dedicated check for CVE-2026-109618 and CVE-2026-109619, run from an attacker's position against your internet-facing web apps and APIs, then pairs every finding with remediation guidance and a retest to confirm the fix held. It answers the question patch tickets cannot: which of your live applications can an attacker still reach through PHP2Shell right now?

Find Every Exposed PHP Application

PHP2Shell is dangerous because it hides in the runtime, and runtimes hide in places inventories miss: a legacy marketing site, a staging host left online a container nobody rebuilt. ZeroThreat maps your external attack surface, from exposed ports, SSL/TLS and DNS through to applications, APIs and authenticated areas, then runs the PHP2Shell check against what it finds. The result is a list of the applications that are actually exposed, not a list of servers that have PHP installed.

ZeroThreat Remediation Guidance for CVE-2026-109618 and CVE-2026-109619

Each PHP2Shell finding ships with the evidence behind it, including the raw request and response, plus step-by-step remediation and an effort estimate. Reports are split by audience, so each team gets what it needs to act without a translation step:

TeamWhat the PHP2Shell finding gives them
Security teamsThe affected asset, its exposure, why it was prioritized and its business impact
Application and platform teamsThe endpoint, request and response evidence, remediation steps and effort estimate

Because the fix for PHP2Shell is a runtime upgrade, the guidance points teams at the patched build and the deployment details that decide whether it takes effect, rather than at application code.

Prioritize by Business Impact, Not Just a 9.2 Score

Every PHP app in your estate shares the same CVSS score, but not the same risk. ZeroThreat ranks findings by what the application protects and how reachable it is, and sorts them into fix windows: Fix immediately, within 7 days, within 30 days and within 90 days. An internet-facing PHP application that handles logins or payments goes to the top of the list, so your first restart is the one that matters most.

Confirm the Fix With a One-Click Retest

Installing a patched package does not prove the running workers picked it up. After you upgrade and restart, a one-click retest runs the PHP2Shell check again from the outside. If a stale worker, an unrebuilt container image or a forgotten parallel install is still serving traffic, the finding stays open. When it closes, you have evidence that the vulnerable runtime is gone, which is also the record auditors and customers will ask for.

ZeroThreat POV

The PHP2Shell bugs sat in PHP's core for decades. Wiz's researchers said turning them into a working exploit required a chain of steps at the edge of what humans could manage by hand, and frontier AI models closed that gap. Attackers have the same models. When old runtime flaws can become exploits in days, testing has to move at the same pace, which is the case for continuous zero-day vulnerability detection rather than an annual pentest.

PHP2Shell Vulnerability Statistics

Key Takeaways

  • PHP2Shell is two runtime flaws, so no application or framework update fixes it.
  • Apache mod_php is the top priority: the demonstrated exploit runs before any application code.
  • Patch to 8.5.12, 8.4.27, 8.3.36 or 8.2.35, or a vendor package with the fixes backported.
  • Stopgaps and WAF rules each block specific paths, and attackers are already mutating payloads around them.
  • Verify the running worker, rotate secrets held in worker memory, and retest from outside.

Find Out Which PHP Apps Are Still Exposed.
Run ZeroThreat's PHP2Shell check from an attacker's position and confirm every fix held.
Start AI Pentesting Free

Conclusion

PHP2Shell is a runtime problem, so the fix is a runtime upgrade. The hard part is proving that every internet-facing PHP process actually picked it up, across branches, containers and forgotten hosts, while attackers are already testing the same servers.

ZeroThreat closes that gap from the outside. Its PHP2Shell check shows which web apps and APIs are still exposed, and application-aware AI pentesting ranks them by business impact. A retest then confirms each fix held, instead of leaving you to trust a package version. Sign up and check your PHP estate today.

Frequently Asked Questions

Why is it called PHP2Shell?

PHP2Shell is the nickname researchers gave CVE-2026-109618 and CVE-2026-109619. It describes the outcome: a crafted HTTP request to a PHP server can end in a shell, meaning arbitrary code running with the privileges of the PHP worker process.

Is PHP2Shell in the CISA KEV catalog?

Are WordPress, Laravel, and Drupal sites affected by PHP2Shell?

Does hiding the PHP version protect against PHP2Shell?

What can I do about PHP2Shell on shared hosting?

Does the PHP CLI need to be updated for PHP2Shell?

Can the patched PHP version change how my application behaves?

How do I tell which PHP handler my server uses?

Explore ZeroThreat

Automate security testing, save time, and avoid the pitfalls of manual work with ZeroThreat.