PHP2Shell

PHP2Shell is the collective name for CVE-2026-109618 and CVE-2026-109619, two critical unauthenticated remote-code-execution flaws in the PHP core engine itself — not in any application running on top of it. Disclosed in October 2026, each is rated CVSS v4.0 9.2 (Critical). Every PHP installation serving web requests is in scope: PHP-FPM, Apache with mod_php, php-cgi, FrankenPHP, and LiteSpeed. The PHP project considers mod_php deployments at highest risk, with a demonstrated exploit where an unauthenticated request triggers the attack before any application code runs.1

The shared root

Both flaws come from abnormal request termination. PHP’s request lifecycle assumes request-owned state is initialized, used, and reset before the request heap is freed; a fatal error or out-of-memory (OOM) abort can interrupt the lifecycle partway, and the persistent worker carries remnants across the request boundary. PHP’s per-request shared-nothing contract is the assumption underneath; both CVEs are violations of it, exploitable across two different requests that land on the same worker.2

CVE-2026-109618 — RCE via OOM corruption

PHP handles OOM errors with longjmp() out of the current context. In some contexts, request memory is reachable before it is fully initialized; if an allocation fails at that point, PHP exits early without accounting for the half-initialized state, and the request shutdown procedure may then read or branch on invalid memory. The failed allocation need not be related to the invalid memory. Multiple OOM strategies trigger this consistently, including several multipart parsing problems that reach OOM while nominally within PHP’s limits: requests without a usable declared content length that pass the post_max_size check, multipart parts with unbounded header counts (cheap on the wire, expensive as PHP structures), and empty file controls with nested field names that evade max_file_uploads accounting.3

Susceptibility varies by SAPI. Apache mod_php unconditionally invokes request shutdown even when startup failed — body parsing during startup can exhaust memory_limit, and shutdown then consumes the invalid state entirely before application code begins. FPM exits the child when startup fails (removing that exact path); source analysis still supports FPM as susceptible via post-startup OOM, though no complete FPM exploit has been demonstrated. FrankenPHP likely shares mod_php’s exposure; LSAPI models FPM.4

The patch removes longjmp() from OOM handling: a delayed graceful soft-OOM at the next VM safe point, plus an immediate hard OOM via _exit() past a second, higher threshold. Shutdown no longer sees invalid state.5

CVE-2026-109619 — RCE via stale global state

Workers keep global state — error, session, object, extension state — that can point into memory owned by one request; that state must be reset before the request heap is freed. The advisory formalizes exploitation as a producer/consumer pair: one request’s operation publishes request-owned state to a worker-global location (producer), a fatal error abandons the matching reset, the heap is freed, and a later request’s operation reads, frees, or branches on the stale value before normal initialization replaces it (consumer). Confirmed producers include parse and compile failures, uncaught errors, require failures, and Maximum execution time exceeded; even a nonfatal diagnostic during late shutdown can repopulate error state after it was cleared. Confirmed consumers run before request initialization: INI diagnostics (with mod_php, .htaccess and php_value/php_admin_* are applied before php_request_startup(); FPM sees the same early path only via frontend PHP_VALUE/PHP_ADMIN_VALUE), and session upload progress — enabled by default, reachable before ordinary session initialization, and requiring no session_start() call.6

Two cases are demonstrated. PHP 8.5’s fatal_error_backtraces stores request-owned backtrace state whose reset is always missed at shutdown — the strongest demonstrated case and the basis of the confirmed mod_php exploit. The session-upload-progress lifecycle is the second: an upload publishes session and decoder state, OOM or another fatal error skips the reset, and a later upload-progress operation consumes the stale globals. Session-lifecycle RCE was validated against both mod_php and FPM. The patch resets the wider family of request-owned state, since any of it surviving past initialization is unsafe.7

Timeline

  • Aug 11, 2026 — the PHP project receives the first reports of the issues (per Sophos).8
  • Oct 17, 2026 — Amazon Threat Intelligence’s MadPot honeypot records the first exploitation attempt, four days before any public disclosure, from an IP on a commercial anonymization network; how the actor obtained exploit information under embargo is unknown.9
  • Oct 20, 2026 — the existence of both flaws becomes public ahead of coordinated disclosure. PHP issues advance notice of a release scheduled for Oct 21, 14:00 UTC, “reserving the right to release earlier should details of either vulnerability become public, or should evidence of active exploitation appear in the wild.”10
  • Oct 21, 2026, 02:00–08:00 UTC — before the 14:00 UTC embargo lift, MadPot sees multiple proof-of-concept exploits (earliest around 02:00 UTC) and further exploitation attempts from varied anonymized infrastructure; varying payloads suggest multiple actors. The PHP team said the PoCs published before patches were not functional.1112
  • Oct 21, 2026 — patches ship (8.5.12, 8.4.27, 8.3.36, 8.2.35, plus minimal source-only backports for 7.4, 8.0, 8.1). Working PoCs appear within hours of the 14:00 UTC release and are used against sensors almost immediately; Cloudflare’s CTO confirms the company was already seeing early in-the-wild attacks behind temporary WAF rules. NCSC UK tells organizations to update immediately or take PHP systems offline. AWS CJ Moses states the flaws are “now being broadly exploited in the wild.”1314
  • Oct 24–25, 2026 — Perplexity security engineer Adel Karimi’s honeypots record evidence of remote code execution against an Apache mod_php installation running PHP 8.4.26, confirming in-the-wild exploitation over the weekend.15
  • Oct 26, 2026 — CISA adds both PHP2Shell CVEs to the Known Exploited Vulnerabilities catalog and mandates that FCEB agencies secure their networks by Thursday.16
  • Oct 28, 2026 — CISA adds Fragnesia (CVE-2026-46300) to KEV after it is chained with PHP2Shell in the wild, under Binding Operational Directive 26-04.17

Exploitation before disclosure

The MadPot record turns this incident into a case study of disclosure-window economics. Amazon’s framing: an embargo protects defenders only until someone else finds the same bug, so the disclosure date is a poor investigation start date — for PHP2Shell, retro-hunts should begin Oct 17 at the latest. Their second lesson is structural: the patch-to-working-exploit window is compressing because AI-assisted analysis makes turning a patch diff or advisory into an exploit cheap, so the old pattern where a few capable actors built exploits and everyone waited for public PoCs is weakening; defenders should measure patch timelines for internet-facing criticals in hours, and invest in detections that don’t depend on a CVE-specific signature that cannot exist before first exploitation. The PHP Foundation separately attributed the disrupted schedule to a pre-disclosure leak of CVE IDs and mitigation advice given to critical-infrastructure providers, which forced the release two days early.1819

Fragnesia chain (CVE-2026-46300)

By late October the campaign story is a chain. Fragnesia (CVE-2026-46300) is a high-severity Linux kernel privilege-escalation flaw — a logic bug in the XFRM ESP-in-TCP subsystem, part of the “Dirty Frag” class — with a public local proof-of-concept that roots major distributions on kernels released before May 13, 2026. CISA added it to KEV on October 28, 2026, warning that it “can be chained with CVE-2026-109618 and CVE-2026-109619 to implant PHP webshells and run commands as root,” and ordered federal agencies to patch under Binding Operational Directive 26-04.20

Dream Security analysts described the operation behind the warnings: a custom weaponization of the PHP2Shell chain paired with the Fragnesia escalation, complete with target lists, exploitation logs, and approximately 40 custom post-exploitation scripts. Their recovered artifacts account for a campaign that rooted 25 servers across the United States, Japan, Taiwan, and South Korea, with the attacker zeroing in on three specific servers in a US government-affiliated environment. PHP2Shell supplies unauthenticated code execution as the web-server user; Fragnesia takes it to root on hosts missing the May kernel fix.21

Mitigation posture

Both advisories state plainly that updating is the only complete fix, and that no complete generic configuration mitigation exists for CVE-2026-109619 — an application, extension, or server path may publish or consume stale state without a predictable log entry.22 Interim measures reduce specific attack paths:

  • memory_limit=-1 set where applications cannot override it (FPM pool php_admin_value or Apache config) removes the controllable OOM behind CVE-2026-109618. It is not complete: an underlying mmap() failure can still reach the vulnerable longjmp() path. Do not use RLIMIT_AS or RLIMIT_DATA — they induce exactly that failure mode. Keep post_max_size low and enforce decoded request size, header counts, part counts, and nesting depth at the frontend.
  • session.upload_progress.enabled=0 and (PHP 8.5) fatal_error_backtraces=0, applied at startup (not ini_set(), not .user.ini), remove the two confirmed producers/consumers for CVE-2026-109619. Restart every worker after any config change and verify effective settings from a live request (phpinfo()), not the PHP CLI.23
  • WAF rules (Cloudflare, Azure) cover specific techniques only. In-process protections such as RASP do not help on mod_php, where CVE-2026-109618 fires before application code runs.

Version support is its own exposure: PHP 8.1 and older are end-of-life as far as the project is concerned (8.2 reaches end of life Dec 31, 2026), so unsupported deployments either take vendor backports or stay vulnerable.24

Exposure and hunting

PHP runs an estimated 75–80% of all websites, WordPress and other CMSes included; VirusTotal estimated over 5.1 million exposed PHP hosts, roughly 3.8 million with at least one port open.25 Palo Alto Networks’ Cortex Xpanse telemetry counted over 22.6 million exposed instances potentially vulnerable to the two CVEs, and Unit 42 reported proof-of-concept exploits in hand and at least one European government taking its website offline as a precaution — exposure counts vary widely with what “exposed” means and who measures it. 26 A flaw in the shared runtime is a textbook common-mode-failure for the web platform — diversity of applications does nothing when the engine beneath them all shares one defect class.

Sophos’s checklist for retrospective hunting (from Aug 1, 2026 forward, the pre-disclosure window): multipart/form-data POSTs to endpoints that do not normally accept uploads and requests carrying PHP_SESSION_UPLOAD_PROGRESS; spikes of memory-exhaustion errors or worker segfaults in PHP/web-server logs; child processes spawned by web servers (shells, interpreters, download utilities); new or modified PHP files in web roots; outbound connections from PHP processes to unexpected destinations; successful admin logins since Aug 1. Their warning is worth keeping: absence of errors in logs is not proof of safety, because a failure can occur before PHP writes the message and historical logs may have excluded the relevant severities.27

  • php — the language page: recurring PHP attack patterns (LFI, poison null byte, XXE) and webshells
  • common-mode-failure — one runtime under most of the web; correlated failure as the default
  • http-request-smuggling — another request-lifecycle parsing bug class at the protocol boundary
  • poison-null-byte-attack — the earlier PHP-era memory-handling bug class at the C-string boundary
  • cyber-losses-vs-ai-capabilities — PHP2Shell is the motivating case for Saxe’s argument that AI-era CVEs get exploited on schedule without moving aggregate damages

Sources

Footnotes

  1. The PHP Group 2026 — Security advisory: Critical remote code execution vulnerabilities, update now ↩

  2. PHP security team — RCE via stale global state (CVE-2026-109619) ↩

  3. PHP security team — RCE via OOM corruption (CVE-2026-109618) ↩

  4. PHP security team — RCE via OOM corruption (CVE-2026-109618) ↩

  5. PHP security team — RCE via OOM corruption (CVE-2026-109618) ↩

  6. PHP security team — RCE via stale global state (CVE-2026-109619) ↩

  7. PHP security team — RCE via stale global state (CVE-2026-109619) ↩

  8. Sophos — Advisory: PHP2Shell Vulnerabilities (CVE-2026-109618, CVE-2026-109619) ↩

  9. CJ Moses 2026 — Amazon Threat Intelligence identifies PHP2Shell exploitation prior to public disclosure in MadPot ↩

  10. The PHP Group 2026 — Security advisory: Critical remote code execution vulnerabilities, update now ↩

  11. CJ Moses 2026 — Amazon Threat Intelligence identifies PHP2Shell exploitation prior to public disclosure in MadPot ↩

  12. Sergiu Gatlan 2026 — Amazon says PHP2Shell exploitation began 4 days before patches ↩

  13. Sergiu Gatlan 2026 — PHP ships emergency patches for critical PHP2Shell flaws ↩

  14. CJ Moses 2026 — Amazon Threat Intelligence identifies PHP2Shell exploitation prior to public disclosure in MadPot ↩

  15. Sergiu Gatlan 2026 — CISA warns of Fragnesia Linux flaw chained in PHP2Shell attacks ↩

  16. Sergiu Gatlan 2026 — CISA warns of Fragnesia Linux flaw chained in PHP2Shell attacks ↩

  17. Sergiu Gatlan 2026 — CISA warns of Fragnesia Linux flaw chained in PHP2Shell attacks ↩

  18. CJ Moses 2026 — Amazon Threat Intelligence identifies PHP2Shell exploitation prior to public disclosure in MadPot ↩

  19. Sergiu Gatlan 2026 — Amazon says PHP2Shell exploitation began 4 days before patches ↩

  20. Sergiu Gatlan 2026 — CISA warns of Fragnesia Linux flaw chained in PHP2Shell attacks ↩

  21. Sergiu Gatlan 2026 — CISA warns of Fragnesia Linux flaw chained in PHP2Shell attacks ↩

  22. PHP security team — RCE via stale global state (CVE-2026-109619) ↩

  23. Sophos — Advisory: PHP2Shell Vulnerabilities (CVE-2026-109618, CVE-2026-109619) ↩

  24. The PHP Group 2026 — Security advisory: Critical remote code execution vulnerabilities, update now ↩

  25. Sergiu Gatlan 2026 — PHP ships emergency patches for critical PHP2Shell flaws ↩

  26. Unit 42 (Palo Alto Networks) — Threat Brief: Critical Vulnerabilities in PHP: CVE-2026-109618, CVE-2026-109619 ↩

  27. Sophos — Advisory: PHP2Shell Vulnerabilities (CVE-2026-109618, CVE-2026-109619) ↩