← Back to Blog
Vulnerability Research10 min read

PHP2Shell: CVE-2026-109618 and CVE-2026-109619

October 21, 2026 · Updated October 28, 2026

On 21 October 2026, Wiz Research disclosed PHP2Shell — a pair of use-after-free bugs in the PHP core engine's fatal-error handling that chain into unauthenticated remote code execution against WordPress, Drupal, Joomla and essentially every PHP application running under FPM or mod_php on PHP 5.4 or later. Tracked as CVE-2026-109618 and CVE-2026-109619, CVSS up to 9.2, patched upstream the same day. This is a pentester-oriented walkthrough: what the bug class actually is, how the chain executes end-to-end, what to look for in authorised engagements, and the remediation evidence a VAPT report needs to carry.

TL;DR

  • Two CVEs: CVE-2026-109618 (upload-progress unserializer UAF, CVSS 9.2) and CVE-2026-109619 (fatal-error backtrace UAF).
  • Vulnerable: PHP 5.4 through 8.5.11. Fixed in 8.5.12, 8.4.27, 8.3.36, 8.2.35 (21 Oct 2026).
  • PHP 8.1 and earlier are EOL — no upstream fix. Move off these branches or rely on distro backports (Debian LTS, Ubuntu ESM, Red Hat).
  • Affects every SAPI that keeps worker state across requests: FPM, mod_php, php-cgi, FrankenPHP, LiteSpeed (LSAPI). CLI is not vulnerable.
  • Chains to unauthenticated RCE on vanilla WordPress, Drupal, Joomla container images with no application-layer flaw required.
  • CISA added both CVEs to the KEV catalog on 26 Oct 2026; US federal civilian agencies must remediate by 16 Nov 2026 (BOD 22-01, 21-day cycle).
  • Internet-wide exploitation attempts have been observed since 17 Oct 2026 — four days before coordinated disclosure. Assume mass scanning.
  • Pentest implication: this is a PHP-stack ground-truth check for every engagement from October 2026 onward.

What PHP2Shell Actually Is

PHP2Shell is not a generic family of web-shell techniques and it is not a class of application bugs. It is a specific memory-safety chain in the PHP interpreter itself. The flaw lives in the request-cleanup path that PHP runs when an allocation fails mid-request on any long-lived SAPI — FPM, Apache mod_php, php-cgi, FrankenPHP, and LiteSpeed's LSAPI are all affected. (CLI is not: it exits per invocation and does not reuse worker state.) The request heap is destroyed on fatal error, but a handful of process-scope globals keep pointers into that freed memory:

  • BG(unserialize) — state for the upload-progress unserializer
  • EG(last_fatal_error_backtrace) — the backtrace captured when the fatal fired
  • CG(map_ptr_last) — OPcache's shared-memory frontier marker

The next request handled by the same long-lived worker reads from or writes through these dangling pointers. The memory they reference has already been freed and can hold attacker-controlled bytes placed by the first request, which turns ordinary PHP functionality into a use-after-free primitive. One mechanism, two CVE IDs reflecting two distinct exploitation surfaces. Clean, modern application code offers no defence — the application is incidental.

The Four Exploitation Primitives

1. Upload-progress unserializer corruption (CVE-2026-109618)

Stale BG(unserialize) state lets an attacker drive controlled deserialisation on the second request. The upload-progress feature is enabled by default on most distributions and does not require authentication to reach, which is why this is the primary RCE primitive and why it carries the higher CVSS of the pair.

2. Memory disclosure via PHPSESSID cookies

Freed heap contents are reflected back in the next request's response cookies. No session_start() call is required for the leak to work. This is the "read" side of the chain — leak pointers from the heap, defeat ASLR, prepare the write primitive. In a pentest it is the easiest-to-demonstrate indicator before you touch anything exploitable: anomalously long PHPSESSID values on a target that is not using sessions.

3. Backtrace pointer reuse (CVE-2026-109619)

EG(last_fatal_error_backtrace) persists across requests on the same worker. A chain of two carefully timed requests gives the attacker a controlled read/write primitive through the dangling backtrace structure. This path is independent of the unserializer and is the usable primitive when the upload-progress extension is disabled or the application tier blocks it.

4. OPcache type confusion

Cross-worker drift in CG(map_ptr_last) advancement causes type confusion in OPcache's shared memory segment. Not strictly required for RCE but hardens the chain against ASLR and heap-grooming entropy, and persists until the FPM pool restarts or OPcache is reset.

Affected and Fixed Versions

Both CVEs affect every PHP release from 5.4 through 8.5.11 running under a persistent-worker SAPI. The 21 October 2026 security releases close the chain:

BranchVulnerable up toFixed inSupport status
PHP 8.5.x8.5.118.5.12Active support
PHP 8.4.x8.4.268.4.27Active support
PHP 8.3.x8.3.358.3.36Security support
PHP 8.2.x8.2.348.2.35Security support
PHP 8.1 and earlierAll— (no upstream fix)EOL — upgrade or distro backport only

PHP 8.1 reached end-of-life in December 2025 and will not receive an upstream patch. Operators still on 8.1 or earlier must either upgrade a supported branch, pull a distribution backport (Debian LTS, Ubuntu ESM, Red Hat Enterprise Linux), or accept the exposure and compensate at the WAF and runtime layers.

What runs the vulnerable code

Wiz demonstrated RCE against the latest container images of WordPress, Drupal and Joomla with no application-layer modification. The real affected list is any PHP application running under a persistent-worker SAPI. In practice:

  • WordPress, Drupal, Joomla, MediaWiki, Nextcloud, OwnCloud
  • Magento, PrestaShop, OpenCart, WooCommerce
  • Laravel, Symfony, CodeIgniter, CakePHP production builds
  • phpMyAdmin, Roundcube, Zabbix and Icinga web UIs
  • Shared / managed PHP hosting on Hostinger, Bluehost, SiteGround, Kinsta, WP Engine, GoDaddy

Affected SAPIs

  • PHP-FPM — the common nginx / Apache-event deployment. Vulnerable.
  • Apache mod_php (prefork/worker/event MPM). Vulnerable.
  • php-cgi — long-lived FastCGI harnesses on legacy shared hosting. Vulnerable.
  • FrankenPHP — the Caddy-based worker-mode SAPI gaining traction in 2026. Vulnerable; patch via the FrankenPHP image that ships bundled PHP ≥ 8.4.27.
  • LiteSpeed (LSAPI) — LiteSpeed, OpenLiteSpeed, CyberPanel. Vulnerable; update the LSPHP binaries, not just the LiteSpeed server.
  • CLI — not vulnerable. Scripts invoked per-request have no cross-request worker state.

Disclosure & Exploitation Timeline

  • 19 Aug 2026 — Wiz Research discovers the first UAF primitive with assistance from frontier AI models
  • 20–21 Aug 2026 — RCE confirmed against Drupal and WordPress container images
  • 24 Aug 2026 — Coordinated disclosure to the PHP security team
  • 21 Sep 2026 — PHP security team begins fix development
  • 17 Oct 2026 — First internet-wide exploitation attempts observed (pre-disclosure). Honeypot and shared-hosting telemetry record OOM-triggering POSTs followed by anomalous PHPSESSID read requests. Source of the pre-disclosure leak unconfirmed.
  • 21 Oct 2026 — Patched PHP releases (8.5.12 / 8.4.27 / 8.3.36 / 8.2.35) ship; Wiz publishes PHP2Shell writeup
  • 26 Oct 2026 — CISA adds CVE-2026-109618 and CVE-2026-109619 to the Known Exploited Vulnerabilities (KEV) catalog. BOD 22-01 remediation deadline for US federal civilian agencies: 16 Nov 2026.
  • 28 Oct 2026 (today) — Mass exploitation ongoing; multiple shared-hosting providers report compromised customer sites.

Pentester Playbook

In an authorised engagement, validate PHP2Shell exposure without weaponising the write primitive. The read-side disclosure (primitive #2) is sufficient evidence of exposure for a VAPT report and does not corrupt worker state.

  1. Fingerprint the stack. Confirm PHP under FPM or mod_php. Check X-Powered-By, error pages, and PHPSESSID cookie presence. Record the PHP minor version if leaked.
  2. Trigger controlled OOM on a benign endpoint. A POST with a crafted memory_limit-exceeding payload against a request-parsing endpoint, within the scoped target set.
  3. Follow-up read request on the same worker. Inspect the response Set-Cookie: PHPSESSID=... for anomalously long values containing non-random byte patterns — the memory disclosure signature.
  4. Stop at proof. Memory disclosure is enough for the finding. Do not drive the unserializer or backtrace primitives in a live engagement without explicit written authorisation — the client's worker state will drift and other tenants may share the pool.
  5. Record the chain of evidence. Timestamped request/response pairs, PHP version string, worker PID if visible, and the disclosed byte sequence. This is the artefact that converts the finding into a CVSS 9.2 critical in the report.

Detection for Defenders

  • Access-log anomalies: PHPSESSID cookie values beyond the normal 26–32 character range, especially on endpoints the application does not call session_start() on.
  • FPM worker logs: bursts of out-of-memory fatals, especially paired with HTTP 500 spikes on multipart upload endpoints.
  • EDR / eBPF: new child processes spawned by php-fpm or httpd workers, outbound connections from webserver processes to unfamiliar IPs, writes to /tmp or /dev/shm followed by execution.
  • WAF rules: block anomalously long PHPSESSID response cookies and multipart requests designed to overrun memory_limit.

Remediation Checklist

  1. Patch PHP to 8.5.12, 8.4.27, 8.3.36 or 8.2.35 from php.net or your distribution feed. On PHP 8.1 or earlier, upgrade a supported branch or pull a Debian LTS / Ubuntu ESM / RHEL backport. Managed hosts (WP Engine, Kinsta, Hostinger, SiteGround) typically patch within hours — confirm the SLA.
  2. Restart workers on every affected SAPI. FPM: systemctl restart php8.4-fpm. mod_php: restart Apache. FrankenPHP: redeploy with the patched image. LiteSpeed: lswsctrl restart plus update the LSPHP binary.
  3. Reset OPcache (opcache_reset() or SAPI restart) in case cross-worker type confusion left poisoned entries.
  4. Hunt back to 17 Oct 2026 for the detection signatures below. Pre-disclosure exploitation attempts have been observed since that date; anything before 17 Oct is pre-exploit for this chain.
  5. Rotate secrets on any host where exploitation is plausible — DB passwords, API keys loaded through getenv(), OAuth client secrets, session signing keys.
  6. If you are a US federal civilian agency, note the CISA KEV listing (26 Oct 2026) carries a BOD 22-01 remediation deadline of 16 Nov 2026.

Why This Survived a Decade

The flaw sits at the intersection of three code paths few reviewers hold in their head simultaneously: PHP's fatal-error handler, the request-cleanup path, and specific extensions (upload-progress, OPcache) that interact with request-scope state. Static analysers do not model cross-request state. Fuzzers struggle because triggering the bug requires chaining two HTTP requests with a controlled out-of-memory failure between them. Wiz credits frontier AI models for compressing the cost of adapting known-but-impractical primitives to specific heap layouts and PHP versions from months of specialist work into hours — a worth-watching pattern for the next decade of vulnerability research.

Related Reading on TigerStrike

Entry points that pre-authenticate PHP2Shell exploitation on legacy stacks are covered separately — see the File Upload Vulnerabilities guide for upload-chain weaknesses and Freemarker SSTI for the template-injection parallel. Those are distinct application-layer bug classes and should not be conflated with PHP2Shell, which is an interpreter-level memory-safety flaw.

Sources

  • Wiz Research: PHP2Shell — PHP RCE, 21 October 2026
  • PHP 8.x ChangeLog, security releases 21 October 2026
  • CVE-2026-109618 and CVE-2026-109619 at NVD (pending)

Where TigerStrike Fits

TigerStrike's continuous pen testing re-runs PHP2Shell probes (the read-side memory disclosure, non-destructively) on every release across your PHP fleet, so the evidence that CVE-2026-109618 and CVE-2026-109619 are closed is dated to the last deploy rather than the last annual assessment. Pair that with runtime detection for the exploitation signatures above and PHP2Shell becomes a solved problem rather than an ambient risk.

Stop finding vulnerabilities manually

TigerStrike uses AI agents to continuously discover, validate, and exploit vulnerabilities across your applications — so your team can focus on fixing what matters.