PHP2Shell: Your Application Code Is Clean, But the Engine Underneath It Isn’t

Red | Vulnerability
PHP2Shell: Your Application Code Is Clean, But the Engine Underneath It Isn’t | HiveForce Labs Threat Advisory
HiveForce Labs · Threat Advisory · Vulnerability Report

PHP2Shell: Your Application Code Is Clean, But the Engine Underneath It Isn’t

Two critical flaws in the core PHP engine, CVE-2026-109618 and CVE-2026-109619, let an unauthenticated attacker run code and read raw worker memory on nearly every PHP release since 5.4, even when the application code on top is fully patched.

Threat Level: RedVulnerability ReportTA2026309Published October 22, 2026Admiralty A1
TA Number
TA2026309
Published
October 22, 2026
Admiralty Code
A1
Threat Level
Red
Report Type
Vulnerability Report
First Seen
August 19, 2026
CVEs
CVE-2026-109618
CVE-2026-109619
CVSS
9.2 v4.0
Affected Versions
5.4 to 8.5.11

01 / Overview

Summary

PHP2Shell is a pair of critical flaws, CVE-2026-109618 and CVE-2026-109619, in the core PHP engine itself rather than in any application built on top of it. A site can be fully up to date and still be exposed simply because it runs PHP. Both flaws carry a CVSS v4.0 score of 9.2 and affect every PHP release from 5.4 through 8.5.11.

An unauthenticated attacker can run code on the server with the web worker's privileges and read raw memory from PHP worker processes, which can contain passwords, session tokens, API keys, and certificates from other users' requests. The flaws allow pre-authentication remote code execution against default WordPress, Drupal, and Joomla deployments, though exploitation does not depend on those platforms at all.

Exploitation came before the fix. The earliest recorded attempt was on 17 October 2026, and the PHP security team shipped an out-of-band emergency release on 21 October 2026: PHP 8.5.12, 8.4.27, 8.3.36, and 8.2.35. PHP 8.1 and older get no full release, only limited source backports for 7.4, 8.0, and 8.1. No threat actor or malware family has been publicly attributed.

Six IPv4 addresses are listed as indicators, but they are shared anonymization infrastructure, so investigate any hits rather than blocking them outright.

Affected Products
PHP (all versions from 5.4 through 8.5.11)
CVEs
CVENameAffected ProductZero-DayCISA KEVPatch
CVE-2026-109618PHP2Shell (PHP Out-of-Memory Corruption Vulnerability)PHP Group PHPNoNoAvailable
CVE-2026-109619PHP2Shell (PHP Remote Code Execution Vulnerability)PHP Group PHPNoNoAvailable

02 / Analysis

Vulnerability Details

  1. #01

    An out-of-band emergency release from the PHP security team on 21 October 2026 addressed two critical remote code execution flaws, CVE-2026-109618 and CVE-2026-109619, grouped under the name PHP2Shell. Both are memory-safety defects in the core engine, and both trace back to the same underlying behaviour. When a request ends abnormally, most often because PHP hits an out-of-memory condition, the engine can tear down the request's heap while internal bookkeeping still points at that freed memory or still holds data that was only partially set up. The worker process survives and goes on to handle the next request, carrying that corrupted state with it. Because PHP workers are reused across requests, an attacker who can reliably trigger the failure can line up their own data in the memory the engine is about to trust.

  2. #02

    CVE-2026-109618 is the out-of-memory corruption path. An out-of-memory error interrupts an operation partway through, leaving request data only partially initialized, and PHP's cleanup routines then process that invalid state as if it were valid. Chaining the weaknesses in this path gives remote code execution running as the web worker account. CVE-2026-109619 is the stale global state path, where PHP keeps references to request-owned data after the backing memory has been freed; a later request handled by the same worker reaches those references before normal initialization resets them, producing a heap use-after-free that has been shown to yield both memory disclosure and remote code execution. The confirmed routes into this second flaw run through session upload-progress handling and, on PHP 8.5, through retained fatal-error backtraces.

  3. #03

    Neither flaw requires authentication, and neither requires the target application to contain a bug of its own, which is what makes the attack surface so large. A minimal “Hello World” script on an affected runtime is exploitable. PHP has stated that the risk is highest for Apache mod_php, where a demonstrated exploit fires before any application code runs at all, and PHP-FPM is not exempt because session-lifecycle remote code execution has been validated against it under suitable application conditions. Every PHP version from 5.4 up to 8.5.11 is affected. The fixes are in PHP 8.5.12, 8.4.27, 8.3.36, and 8.2.35. PHP 8.1 and anything older is past end of life, so those branches get no full release at all, and the project has published limited source backports for 7.4, 8.0, and 8.1 instead.

  4. #04

    Both CVEs carry a CVSS v4.0 base score of 9.2, placing them in the Critical band, which reflects unauthenticated network-reachable exploitation leading to full compromise of confidentiality, integrity, and availability. The attack traffic against these flaws was observed before patches were publicly available.

Vulnerabilities
CVE IDAffected ProductsAffected CPECWE ID
CVE-2026-109618PHP Group PHP (5.4 through 8.5.11)cpe:2.3:a:php:php:*:*:*:*:*:*:*:*CWE-1325, CWE-416, CWE-755, CWE-824
CVE-2026-109619PHP Group PHP (5.4 through 8.5.11)cpe:2.3:a:php:php:*:*:*:*:*:*:*:*CWE-1325, CWE-416, CWE-755, CWE-824

03 / Action Plan

Recommendations

  1. 01
    Patch PHP Right Away

    Update to PHP 8.5.12, 8.4.27, 8.3.36, or 8.2.35, whichever matches your branch. This is the only complete fix. PHP 8.2 itself reaches end of life on 31 December 2026, so patching to 8.2.35 buys roughly ten weeks; plan the move to 8.3 or later now. If you are on PHP 8.1 or older, those branches are past end of life and will not get a full release, so either pull a backported build from your Linux distribution or LTS vendor, apply the limited source backports PHP published for 7.4, 8.0, and 8.1, or move to a supported version.

  2. 02
    Start With Your Internet-Facing mod_php Servers

    PHP has flagged Apache mod_php as the highest-risk configuration because a demonstrated exploit can fire before any of your application code runs. Work outward from there to PHP-FPM, php-cgi, lsphp, FrankenPHP, and LiteSpeed deployments. Anything that serves web requests and is reachable from the internet should be at the front of the queue.

  3. 03
    Apply Temporary Mitigations Only If You Cannot Patch Today

    For CVE-2026-109618, set memory_limit=-1 in a way applications cannot override, such as php_admin_value in the FPM pool or Apache configuration, keep post_max_size low at 8M without uploads or 32M with them, and use container or cgroup limits as an availability boundary. Do not substitute RLIMIT_AS or RLIMIT_DATA, which PHP warns can themselves trigger the vulnerable allocation failure. For CVE-2026-109619, set session.upload_progress.enabled=0 before request parsing and restart every worker, and on PHP 8.5 also set fatal_error_backtraces=0. Treat all of these as stopgaps that close known paths, not as protection.

  4. 04
    Hunt for Signs of Compromise

    Because these flaws execute below the application layer, your application logs may show very little. Look instead for unusual multipart requests followed by memory-limit errors or repeated HTTP 500 responses, unexpectedly large or malformed PHPSESSID response cookies, and unexplained PHP worker churn. Because these flaws can disclose raw worker memory, treat credentials, session tokens, and API keys that lived on an exposed server as potentially compromised and rotate them.

  5. 05
    Edge Blocking for CVE-2026-109618

    Block form field names of 1,000 bytes or more. Every variant of this flaw needs a field name large enough that copying the key exhausts memory_limit during request startup, which in practice means megabytes, so a 1 KB threshold sits far below the exploit minimum and still produces no false positives. Match names and not values by anchoring at a field boundary on urlencoded bodies, and cover the multipart variant separately by checking part header name lengths. Never gate on Content-Length, because chunked requests do not carry one and HTTP/2 does not require one, which makes a header-based size check a one-line bypass. As a backstop, rate-limit large POSTs to roughly ten per source IP per minute.

  6. 06
    Edge Blocking for CVE-2026-109619

    Exploit bodies here run to roughly 450 bytes with short field names, so there is nothing to size-limit. Instead block three multipart shapes that no legitimate client sends, matching on part headers only so that uploaded file contents never trigger the rules. First, a PHPSESSID form field, since the upload handler copies it into the session ID without checking session.use_only_cookies and real clients send session IDs in the Cookie header. Second, a PHP open tag in a filename, limited to the full and short echo tags to avoid false positives on XML-style names. Third, serialized-object syntax in a filename, which is how the handler-mismatch chain writes its payload. Log the PHP_SESSION_UPLOAD_PROGRESS field but do not block on it, because that is the legitimate progress-bar mechanism. These rules stop the write to the session file but not a later local file inclusion read, so purge session.save_path as part of the rollout.

  7. 07
    PHP Fatal Error From an Unknown Script

    In Apache or Nginx error logs, look for messages containing PHP Fatal error together with “tried to allocate” and “in Unknown on line 0”. Ordinary application memory exhaustion names the file and the line responsible, so the Unknown on line 0 phrasing means the allocation happened outside normal script execution. Treat this as a high-priority lead rather than proof, because it is not unique to PHP2Shell, and correlate it with oversized POSTs, connection resets, and worker crashes from the same source.

  8. 08
    Web Server Spawning a Shell

    Look for process events where the parent is apache2, httpd, nginx, lighttpd, caddy, php-cgi, php-fcgi, php-fpm, lsphp, or frankenphp, or where the process runs as a web server account such as apache, www-data, or nginx, and the child process is a shell such as sh, bash, dash, zsh, or ksh. Narrow on command lines containing -c or -lc alongside suspicious content such as id, whoami, hostname, nc, ncat, socat, xxd, base64, openssl, curl, wget, chmod, python, perl, /dev/tcp, /dev/shm/, /tmp/, /.ssh, /etc/passwd, or /etc/shadow. Web servers do legitimately spawn shells in some environments, so this one needs tuning.

  9. 09
    Post-Exploitation Hunting

    The exploit runs shell commands as the web server user without crashing the worker, so there may be no visible disruption at all. Look for unexpected child processes of web server and PHP workers, files created or modified in /tmp, /dev/shm, /var/tmp, or web-writable directories by the web server user, and outbound connections from that user on non-standard ports. In logs, look for bursts of HTTP 200 responses to large POSTs from a single source carrying Allowed memory size errors, since each successful attempt returns a 200, and for hundreds of large POSTs from one address producing AH00052 child process exit entries in Apache error logs. For persistence, check new or modified SSH authorized_keys files under web server user home directories or /var/www, new cron entries for that user, and unfamiliar PHP files in web roots. Cover the period from 17 October 2026, the earliest recorded exploitation attempt, rather than from the disclosure date or the date you patched.


04 / Detection

Indicators of Compromise (IoCs)

TypeValue
IPv4103[.]216[.]220[.]92
31[.]223[.]184[.]166
37[.]19[.]200[.]5
134[.]209[.]159[.]64
103[.]114[.]163[.]188
95[.]217[.]98[.]37

These IPs are shared anonymization infrastructure; investigate any hits rather than blocking them.


05 / Adversary Behaviour

MITRE ATT&CK TTPs

T1190
Initial Access
Exploit Public-Facing Application
T1059
Execution
Command and Scripting Interpreter
T1505
Persistence
Server Software Component
T1505.003
Server Software Component › Web Shell
T1098
Account Manipulation
T1098.004
Account Manipulation › SSH Authorized Keys
T1053
Scheduled Task/Job
T1053.003
Scheduled Task/Job › Cron
T1033
Discovery
System Owner/User Discovery
T1212
Credential Access
Exploitation for Credential Access
T1211
Defense Evasion
Exploitation for Defense Evasion

06 / Sources

References & Patch Links

Patch Link
References

Reduce real exposure. Not just vulnerability volume.