Back to Blog
Insights

PHP2Shell (CVE-2026-109618 / CVE-2026-109619) — Pre-Auth RCE in Core PHP, Explained

PHP2Shell (CVE-2026-109618 / CVE-2026-109619) — Pre-Auth RCE in Core PHP, Explained

On 21 October 2026 at 14:00 UTC, the PHP project shipped emergency security releases for PHP2Shell — a coordinated pair of memory-safety vulnerabilities in the PHP engine itself, tracked as CVE-2026-109618 and CVE-2026-109619 (CVSS v4.0 9.2, Critical). The bugs live in core PHP, affect every unpatched PHP since 5.4 (released 2012), and chain to unauthenticated remote code execution with the privileges of the PHP worker. Cloudflare reported early attacks at 07:43 UTC the same morning — before the patch was even published. If you operate anything PHP — WordPress, Magento, Laravel, Drupal, a homegrown app — this is an update-the-runtime-now event, because no application code change can fix it.

To be clear about provenance: IKZERO did not discover these vulnerabilities. This is our technical read of the disclosures from Wiz Research, Calif, OpenAI Codex Security and the PHP Foundation, plus the operational guidance from Sansec and the national CSIRTs, written for the teams who need to act on it.

Why this one is different

Most PHP vulnerabilities live in applications or plugins. PHP2Shell lives in the interpreter — the layer beneath every PHP application. Three properties make it dangerous:

  • App-agnostic. Researchers demonstrated pre-auth RCE against WordPress, Drupal and Joomla on their latest container images — and note that exploitation does not require those applications at all. A "Hello World" PHP app on an affected runtime is in scope.
  • Pre-authentication and below the app. The vulnerable code paths — multipart body parsing, session upload progress, fatal-error handling — run before your application code. Your WAF rules tuned to your app's logic are not watching this layer.
  • A memory-theft primitive on its own. CVE-2026-109618 can return freed worker memory to the attacker inside a PHPSESSID response cookie — potentially containing passwords, session tokens, API keys and TLS private keys from other requests — without ever executing code.

The two bugs

Both CVEs are use-after-free conditions with the same root pattern: a fatal error during request processing — classically out-of-memory when a request crosses memory_limit — interrupts native PHP code before it cleans up. The freed memory is then treated as live data by a reused worker or a later request.

CVEWeaknessImpact
CVE-2026-109618Upload-progress unserializer use-after-freeMemory disclosure and RCE
CVE-2026-109619Fatal-error backtrace use-after-free; OPcache type confusionRCE

The memory-disclosure path deserves emphasis: PHP's upload-progress handler runs even when your application never calls session_start(), and it can hand freed worker memory back inside a PHPSESSID cookie. That is data theft with a low forensic footprint — no webshell, no suspicious process — which is exactly why "no malware found" does not mean "not breached."

The findings came from three independent teams — Ryan Austin of Calif (first to report, 11 August), Wiz Research (24 August), and OpenAI Codex Security — with the PHP security team coordinating. A second, operational fact worth sitting with: both the discovery and parts of the exploit development were AI-assisted, and the first observed attacker in the wild is reported to have used an AI-assisted chain as well.

Are you affected?

PHP branchStatus
8.2 < 8.2.35Vulnerable → update to 8.2.35
8.3 < 8.3.36Vulnerable → update to 8.3.36
8.4 < 8.4.27Vulnerable → update to 8.4.27
8.5 < 8.5.12Vulnerable → update to 8.5.12
8.1 and older (EOL)Vulnerable, no official release → distro backport or vendor LTS

Both mod_php and PHP-FPM are affected. The vulnerable code dates to 5.4.0, so "we've been running this version for years" is not reassurance — it's the exposure window.

EOL runtimes have no php.net release. Backports exist from: ppa:ondrej/php / deb.sury.org (5.6–8.1), Ubuntu (8.1 on 22.04; Ubuntu Pro for older), Remi's repository (RHEL/Alma/Rocky/Fedora), AlmaLinux (all shipped streams), Red Hat (RHSB-2026-013), CloudLinux (cPanel ea-php52–ea-php85), TuxCare and ZendPHP LTS. Verify the fix landed in the package changelog:

# Debian/Ubuntu (substitute your version)
zgrep CVE-2026-109618 /usr/share/doc/php8.3-common/changelog.Debian.gz
# RHEL/Alma/Rocky
rpm -q --changelog php-common | grep CVE-2026-109618

After updating: restart Apache, PHP-FPM and any long-running PHP workers. A patched binary that is still running in memory is still vulnerable.

What's real about exploitation — and what isn't

The discourse around PHP2Shell has oscillated between "internet-ending" and "overhyped." Here is the honest middle:

What's real: pre-auth RCE was demonstrated on current, stock builds of WordPress, Drupal, Joomla, Magento 2.4.9, MediaWiki, Roundcube, phpMyAdmin, Nextcloud, Laravel, Symfony and WHMCS by the research teams. Cloudflare observed attack traffic within hours of the details leaking. A suspected China-linked actor reportedly used an AI-assisted PHP2Shell chain to root 25 servers in a US government-affiliated environment (per The Hacker News).

What's hard: unlike Log4Shell or Shellshock, there is no known single request that works against any vulnerable server. PHP2Shell attacks need target-specific knowledge and specific server conditions. Independent testing found the public PoCs do not work against a default PHP installation — several require the target application to also have a local file inclusion bug. That is a real limiter on mass scanning-driven exploitation.

The conclusion is the same either way: the conditions are target-specific, not rare, and the memory-disclosure variant needs even less. Dutch sites including Tweakers and the House of Representatives went offline as a precaution on release day — a defensible choice for high-value targets, an overreaction for everyone else. Update PHP; don't panic-unplug.

If you cannot update immediately: partial mitigations

These are stopgaps with real breakage potential — none is a fix.

1. Block multipart/form-data at the web server. Every known trigger is a multipart request, parsed by PHP before your app runs:

# nginx — every server{} block that serves PHP
if ($http_content_type ~* "multipart/form-data") { return 403; }
# Apache — every <VirtualHost> serving PHP
RewriteEngine On
RewriteCond %{HTTP:Content-Type} multipart/form-data [NC]
RewriteRule ^ - [F]

This breaks file uploads and some cart/checkout forms — test ordering flows before you rely on it, and remove it after patching.

2. PHP settings (mod_php: php.ini; PHP-FPM: every pool's www.conf, then reload):

session.upload_progress.enabled = 0
display_errors = 0
fatal_error_backtraces = 0   ; where supported

A PHP core developer has warned that disabling upload-progress alone is not sufficient — combine with the multipart block. memory_limit = -1 neutralizes some OOM-triggered paths but hands exhaustion to the OS: if you use it, contain workers with cgroup v2 memory.max, and do not substitute RLIMIT_AS/RLIMIT_DATA — the PHP advisory warns those can trigger the same vulnerable failure paths. Lowering post_max_size and max_input_nesting_level reduces attacker-controlled memory pressure.

3. Recycle workers faster. Lower PHP-FPM pm.max_requests to flush stale state sooner — a performance cost, and it does not cover single-request paths.

4. Constrain blast radius. SELinux/AppArmor policies limiting what PHP workers can execute reduce post-exploitation impact without preventing exploitation.

A final caution: the fix introduces a new hard memory limit — reaching it terminates the worker and prevents shutdown handlers. Review memory_limit against real application usage after upgrading, and revisit any temporary memory_limit = -1.

How to look for exploitation

No single rule covers every path. Investigation signals, from the disclosure teams:

  • Unusually large or malformed PHPSESSID response cookies — the signature of CVE-2026-109618's memory leak. Grep your access logs for oversized Set-Cookie values on PHP routes.
  • Unusual multipart requests followed by memory-limit errors or clusters of HTTP 500s.
  • Unexplained PHP worker crashes or restarts in FPM logs.
  • Data-theft-only attacks may leave no application-log trace at all, because the vulnerable code runs below the application layer. Absence of signals is not absence of exploitation.

If you find these patterns predating your patch date, treat secrets in worker memory — session tokens, API keys, TLS keys — as potentially disclosed and rotate accordingly.

The bigger picture

Two of the three discovery teams used frontier AI models in the loop, and the first reported in-the-wild operator did too. Eight weeks elapsed between the first responsible report and a patched global release — the system worked — but the same tooling that compresses researcher months into days is now equally available to attackers, and exploit chains that once required a specialist are becoming reproducible. That shift is exactly why our AI security practice now treats AI-assisted offensive capability as a planning assumption, not a hypothetical.

A use-after-free beneath every PHP application on the internet is the class of bug we hunt for in a penetration test, and the log-signature hunting above is daily work in our managed SOC. If you don't know which PHP runtimes you operate — including the ones inside appliances, containers and vendor products — talk to us and we'll map it with you.

Frequently Asked Questions

Do I need a specific application like WordPress to be vulnerable?

No. The bugs are in the PHP interpreter itself. WordPress, Drupal and Joomla were demonstration targets, but any PHP application — including a trivial one — on an unpatched runtime is exposed to at least the memory-disclosure path, and conditions permitting, RCE.

Are shared hosting and cPanel servers affected?

Yes, if their PHP build is unpatched. CloudLinux publishes fixed cPanel packages (ea-php52 through ea-php85); Plesk and DirectAdmin deliver fixes through their panel updates — check each panel's changelog for CVE-2026-109618/109619 before assuming safety.

Is memory_limit = -1 a safe mitigation?

It is a partial, temporary one. It removes some OOM-triggered paths but shifts exhaustion to the OS, so pair it with cgroup v2 memory.max and never substitute RLIMIT_AS/RLIMIT_DATA, which can trigger the same bug family. The fixed releases include a new hard memory limit — revisit this setting after patching.

How do I verify my server is actually fixed?

Check the running PHP version (php -v is not enough for FPM — check via phpinfo() on a served request or the FPM master's binary), confirm the CVE appears in the package changelog, and confirm the workers were restarted after the update. A patched package with months-old FPM workers is not patched.

Was PHP2Shell exploited in the wild?

Yes, in limited fashion. Cloudflare observed attack traffic on release morning before the patch published, and a suspected China-linked actor reportedly used an AI-assisted chain to root 25 servers in a US government-affiliated environment. Mass scanning-driven exploitation has been limited because attacks need target-specific conditions — but memory disclosure is quiet and conditions are not rare.


Sources: Wiz Research and the php2shell.com disclosure hub; Calif; OpenAI; PHP Foundation (21 Oct 2026); Sansec; NCSC-NL; Ubuntu/RHSB/AlmaLinux advisories. Exploit details above are defensive-level and already public.

Get Started

Want a security-first build?

Get a free security review. We'll look at where you stand today and tell you what to fix first, no strings attached.

Talk to an Expert
PHP2Shell (CVE-2026-109618 / CVE-2026-109619) — Pre-Auth RCE in Core PHP, Explained - IKZERO