Zscaler Blog

Get the latest Zscaler blog updates in your inbox

Security Research

CVE-2026-109618 and CVE-2026-109619: PHP Vulnerable to Unauthenticated RCE Attacks

JITHIN PRAJEEV NAIR, AMIR MOIN
October 21, 2026 - 12 min read
>CVE-2026-109618 and CVE-2026-109619: PHP Vulnerable to Unauthenticated RCE Attacks

*October 26, 2026: This advisory has been updated to clarify language describing exploitability and potential impact.

*October 23, 2026: This advisory has been updated with new ThreatLabz analysis and Zscaler Deception telemetry on exploitation activity observed during the first 48 hours following disclosure.

Introduction

On October 21, 2026, two critical remote code execution (RCE) vulnerabilities, CVE-2026-109618 and CVE-2026-109619, collectively referred to as “PHP2Shell,” were publicly disclosed. Both vulnerabilities carry a CVSS v4.0 score of 9.2 out of 10. The PHP security team has released emergency patches and strongly encouraged all PHP users to update immediately. These flaws reside in the PHP core language runtime and successful exploitation could allow an unauthenticated remote attacker to achieve remote code execution on any server running a vulnerable version, potentially enabling unauthorized access, data theft, or further system compromise. Given PHP's pervasive deployment across web infrastructure globally - including applications like WordPress, Drupal, Joomla, and Magento, as well as embedded devices and similarly overlooked public-facing platforms - the potential attack surface is significant. The vulnerabilities could enable automated exploitation of exposed, vulnerable PHP deployments without authentication or user interaction. The vulnerabilities therefore may be attractive targets for exploitation.

ThreatLabz analysis indicates that attackers began rapidly targeting these vulnerabilities following public disclosure, highlighting the need for organizations to patch vulnerable PHP deployments immediately.

Zscaler’s security team has analyzed this issue across both production and corporate environments and has ruled out any impact to Zscaler Cloud Platforms, products, distributed components, services, or our enterprise environment, as detailed in the Trust post.

For more on PHP2Shell and its implications for enterprise security, watch our webinar with EVP, Cybersecurity Deepen Desai and Director of Threat Research Jithin Nair.

Recommendations

Organizations running PHP should take the following actions:

  1. Patch immediately: Upgrade PHP to one of the fixed versions: 8.5.12, 8.4.27, 8.3.36, or 8.2.35. Linux package maintainers received patches in advance and may already have updated packages available. PHP packages for most Linux distributions may also include the patches backported to previous versions of the software, so consult the release notes for your specific installation to ensure your systems are covered.
  2. Deactivate unpatched instances: Consider fully disabling services for any PHP instance that cannot be immediately patched. While this may seem overly cautious, any unpatched instance could be targeted by opportunistic adversaries and result in shell-level access to the vulnerable host. 
  3. Inventory PHP deployments: Conduct an immediate inventory of all PHP installations across your environment, including standalone servers, vendor appliances, bundled software (WordPress, Magento, WooCommerce, Shopware), and hosting panels (cPanel, Plesk, etc).
  4. Migrate off EOL branches: Organizations running PHP 5.4+, 7.x, 8.0, or 8.1 must migrate to a supported branch immediately. No official binary patches will be released for these versions.
  5. Isolate EOL instances that cannot be immediately migrated: Migrating EOL instances is strongly recommended. If this is not possible, isolating unpatchable applications from the internet and other untrusted networks may provide some level of protection. This should be considered a high-risk mitigation and reserved only for business and mission-critical applications while implementing aggressive monitoring of these instances.
  6. Monitor for exploitation: Audit web server logs (including but not limited to Apache, Nginx, etc.) for unusual segmentation faults, crash dumps, or abnormal memory usage patterns that may indicate active exploitation attempts.
  7. Mitigate risk through PHP settings: While not a definitive fix, mission critical applications that cannot be disabled or immediately patched may benefit from reviewing and tightening memory_limit and max_execution_time settings in php.ini to avoid triggering OOM conditions. Consult additional guidance regarding mitigations through setting session.upload_progress.enabled = Off and disabling multipart uploads at the service edge.


ThreatLabz Observes Exploitation Attempts Within 48 Hours

ThreatLabz observed scanning activity and possible exploitation attempts targeting the PHP2Shell vulnerabilities using multiple attack tools and exploitation methods, including RCE payloads, PHP object injection, and named exploitation frameworks, indicating rapid, in-the-wild exploitation attempts.

In the first 48 hours after the PHP2Shell disclosure, Zscaler’s global decoy mesh observed 1,156 exploitation attempts from 156 unique attacker IPs targeting 70 organizations. As a rapid response measure, a new detection rule for PHP2Shell exploitation has been pushed to all Zscaler Deception customers.

Attack chain

Automated scanning activity observed by Zscaler suggests attackers may be attempting to use a two-stage PHP2Shell exploitation chain, as shown in the figure below.

Notional exploit chain consistent with scanning and exploit attempts observed by ThreatLabz.

Figure 1: Notional exploit chain consistent with scanning and exploit attempts observed by ThreatLabz.

Stage 1: State setup and fatal trigger

The attacker sends a crafted multipart/form-data POST request containing:

  1. A PHPSESSID field to associate the request with a known session, making the session filename (sess_[PHPSESSID]) predictable.
  2. The PHP_SESSION_UPLOAD_PROGRESS field to force PHP to begin session bookkeeping during multipart parsing, populating vulnerable global state pointers and writing attacker-controlled data into the session file.
  3. A file attachment whose filename= parameter contains either PHP code or a serialized object string.
  4. A body sized or structured to exhaust memory (CVE-2026-109618) or trigger a fatal error (CVE-2026-109619).

When the fatal condition is triggered, longjmp() aborts the request, freeing per-request memory but leaving stale global pointers.

Stage 2: Heap reclaim and code execution

The attacker immediately sends a second request to the same worker process. This second request contains the attacker's payload, sized and aligned to reclaim the freed memory slots. When PHP processes the new request and references the stale global state before re-initialization occurs, it reads and executes the attacker-controlled data, achieving arbitrary code execution with the privileges of the PHP worker process.

Zscaler Deception telemetry findings

ThreatLabz observed malicious POST requests targeting the PHP2Shell exploitation path across multiple tools and stages of the attack chain. Every observed request is a multipart/form-data POST targeting PHP endpoints, specifically /, /index.php, /api/endpoint.php, and /app/upload.php.

Exploitation payloads observed

1. ShellFlow PHP2Shell named exploit tool

The most forensically significant artifact is the presence of a multipart boundary string that explicitly names the exploitation tool. This indicator should not be considered durable, as an adversary can trivially replace the known strings with something less obvious. At this time, the ShellFlow tool uses a known boundary value, so it is a useful indicator for detecting the unmodified tool. The exploit tool request is shown below. 

POST / HTTP/1.1
Content-Type: multipart/form-data; boundary=----shellflow-php2shell

------shellflow-php2shell
Content-Disposition: form-data; name="PHPSESSID"

sf618_ec172709c8b74601
------shellflow-php2shell
Content-Disposition: form-data; name="PHP_SESSION_UPLOAD_PROGRESS"
shellflow_poc

------shellflow-php2shell
Content-Disposition: form-data; name="f"; filename="poc.bin"
Content-Type: application/octet-stream

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA[...15485 bytes total...]

The multipart boundary shellflow-php2shell identifies the attacking tool by name. The poc.bin file body contains more than 15k bytes of data along with a repeated AAAA... characters, a characteristic heap spray pattern used for memory layout control in the CVE-2026-109618 OOM corruption path.

Notable characteristics:

  • The boundary string shellflow-php2shell directly identifies the ShellFlow PHP2Shell attacking tool, which is publicly linked to CVE-2026-109618 scanning activity.
  • The session ID sf618_ec172709c8b74601 contains sf618, possibly reflecting a developer’s shorthand reference to ShellFlow + CVE-2026-109618.
  • The application/octet-stream upload with a repeating AAAAA... buffer is consistent with a heap spray technique used to influence the memory layout when the OOM condition is triggered.

2. Active system() command execution payload

These requests represent the strongest indication of automated exploitation attempts. The filename= field contains a fully formed PHP webshell instruction designed to be written into the PHP session file through the session.upload_progress handler and later executed, as shown in the example below.

Image

The filename= value [?php system('echo 'exploited digga' > pwned.txt');echo 'RCE';?] instructs the PHP runtime to:

  1. Execute the OS command echo 'exploited digga' > pwned.txt, writing a proof-of-compromise marker to disk.
  2. Echo the string RCE in the HTTP response body, providing an indication of successful code execution to the attacker. The RCE string may still be returned even if the preceding echo redirection fails.

This payload pattern was observed in two separate requests with identical content, consistent with automated retry behavior commonly seen in exploit frameworks.

3. PHP object injection via pipe delimiter

ThreatLabz also observed a PHP object injection request that abuses the session pipe delimiter, as shown in the example. The filename x|O:8:"stdClass":0:{} uses the PHP default session serialization format, where the | character separates a variable name from its serialized value.

POST /app/upload.php HTTP/1.1
Content-Type: multipart/form-data; boundary=--NeoMM2026
--NeoMM2026
Content-Disposition: form-data; name="PHPSESSID"
neosc4n00000000000000002
--NeoMM2026
Content-Disposition: form-data; name="PHP_SESSION_UPLOAD_PROGRESS"
neo_obj_inject
--NeoMM2026
Content-Disposition: form-data; name="f"; filename="x|O:8:\"stdClass\":0:{}"
Content-Type: text/plain
Z
--NeoMM2026--
Image

Overall attack tool fingerprinting summary

ThreatLabz identified multiple distinct attacker toolsets through analysis of numerous requests in our telemetry, as summarized in the table below:

Tool / Framework

Identifying Markers

ShellFlow PHP2Shell

Boundary shellflow-php2shell; session ID prefix sf618; poc.bin heap spray

Active RCE Operator

Boundary --VERIFY; system() payload in filename=; pwned.txt write

Nuclei CVE Templates

Boundary prefix ------Nuclei; echo-test random token in filename

Neo Scanner

Boundary --NeoMM2026b / --NeoMM2026; targets /api/endpoint.php, /app/upload.php

Table 1: Attacker tools and identifying markers observed in PHP2Shell exploitation activity.

Affected Versions

All PHP versions from 5.4 onward are vulnerable. Only currently supported branches received patches, but package maintainers may also backport the security patches to previous versions. Carefully review the instructions and release notes from the maintainers of your PHP installations to determine what version and release includes the necessary patch.

PHP Branch

Vulnerable Versions

Patch Available

PHP 8.5

8.5.0 – 8.5.11

Yes (8.5.12)

PHP 8.4

8.4.0 – 8.4.26

Yes (8.4.27)

PHP 8.3

8.3.0 – 8.3.35

Yes (8.3.36)

PHP 8.2

8.2.0 – 8.2.34

Yes (8.2.35)

PHP 8.1

All versions (EOL)

No (EOL — upgrade required)

PHP 8.0

All versions (EOL)

No (EOL — upgrade required)

PHP 7.x

All versions (EOL)

No (EOL — upgrade required)

PHP 5.4+

All versions (EOL)

No (EOL — upgrade required)

Table 2: CVE-2026-109618 and CVE-2026-109619 Affected PHP Versions and Patch Availability

How It Works

Both vulnerabilities are use-after-free memory safety flaws in PHP's core request-handling engine. All PHP installations serving web requests may be affected regardless of security controls. The vulnerabilities can allow unauthenticated attackers to execute code on affected servers or read sensitive process memory; that memory may contain passwords, authentication tokens, API keys and certificates belonging to other requests or the server itself.

CVE-2026-109618: OOM Corruption / Uninitialized Memory Use

  • CVSS v4.0: 9.2 - Critical

  • Root Cause: PHP uses longjmp() to abort a request when it hits its configured memory limit. When a web application receives form input, PHP records new entries in its internal POST data structure before finishing their initialization. If an out-of-memory (OOM) error fires while internal request data is only partially initialized, longjmp() bypasses normal control flow, leaving memory in an inconsistent/uninitialized state. During request cleanup, PHP misinterprets this invalid data as valid and follows an attacker-controlled code pointer, yielding control of execution.

  • Exploit Vector: An attacker can intentionally trigger specific OOM conditions (e.g., via large memory allocations, deeply recursive calls, or maliciously crafted request payloads) to corrupt state and achieve unauthenticated RCE.

  • Impact: Unauthenticated Remote Code Execution

CVE-2026-109619: Use-After-Free / Stale Memory Access

  • CVSS v4.0: 9.2 - Critical

  • Root Cause: When PHP encounters a fatal error and calls zend_bailout() (via longjmp()), request-owned internal state can survive in global memory after its backing allocation has been freed. PHP workers process multiple requests in sequence, and certain internal pointers persist between requests. If a request crashes or exhausts memory at the right moment, those pointers are left pointing to already-recycled memory. A subsequent request processed by the same worker may access this stale memory before re-initialization occurs.

  • Exploit Vector: This vulnerability is chainable with CVE-2026-109618. The partial initialization in CVE-2026-109618 allows an attacker to shape the freed memory contents and gain control of the instruction pointer, potentially enabling RCE. Chaining these two CVEs requires no authentication and no user interaction.

  • Impact: Unauthenticated Remote Code Execution and memory/credential disclosure

Conclusion

PHP2Shell represents a significant security issue because of the severity of the vulnerabilities and PHP’s broad deployment. The combination of CVE-2026-109618 and CVE-2026-109619 could provide an unauthenticated path to RCE and potentially broader server compromise without user interaction.

Organizations are strongly urged to treat this as an emergency patching event. Systems running EOL PHP branches must be migrated without delay. Where patching cannot be completed immediately, network-layer controls should be applied as an interim measure.

ThreatLabz will continue to monitor active exploitation campaigns and update Zscaler platform protections as new indicators emerge.

How Zscaler Can Help

The following table shows the typical attack stages and the mitigations recommended by Zscaler.

Attack Stage

Recommended Mitigation

Minimize the external attack surface

  • Identify and fix any vulnerable PHP applications with Zscaler Exposure Management
  • Eliminate externally exposed PHP assets by leveraging a Zero Trust architecture.

Prevent compromise

Prevent lateral threat movement

  • Use ZPA to enforce least-privilege user-to-app segmentation for crown-jewel apps (employees and third parties).
  • Use ZPA inline inspection to block exploitation attempts against private apps from compromised users.
  • Use Zscaler Deception to detect and contain lateral movement or privilege escalation with decoy assets and accounts.
  • Use Zscaler MDR and Threat Hunting to detect and respond to early stage threat activity.

Prevent data loss

  • Inspect outbound traffic across channels with Zscaler DLP.


Zscaler Coverage

The Zscaler ThreatLabz team has deployed protections for CVE-2026-109618 and CVE-2026-109619 with the following signatures:

Zscaler Advanced Threat Protection

The Zscaler Advanced Threat Protection signatures detect exploitation attempts from ZIA traffic targeting internet-exposed servers:

Zscaler Private Access AppProtection

The ZPA App Protection signatures detect exploitation attempts against internal applications through ZPA, including activity originating from compromised endpoints or insiders:

Zscaler Deception 

Zscaler Deception customers can deploy Private Threat Intelligence decoys for the following applications to detect PHP2Shell exploitation attempts and generate high-fidelity alerts:

  • WordPress Login
  • Drupal Admin Panel
  • Joomla Admin Panel
  • phpMyAdmin
  • Nextcloud

Customers can configure an orchestration rule to add any IP addresses interacting with these decoys to a firewall block list.

Zscaler MDR

Zscaler MDR's behavioral detection analytics also provide generic coverage for this class of web application RCE. The following active detection analytics are candidates for identifying post-exploitation activity that may result from these vulnerabilities:

  • NIX-WEBSERVER-SPAWN-SUSPICIOUS-COMMAND — Linux web servers spawning suspicious commands including reconnaissance utilities and downloaders
  • NIX-WEBSERVER-SPAWN-RECON — Web servers spawning reconnaissance commands
  • PSX-WEBSERVER-CREATE-PHP-SCRIPT — Web servers creating inline PHP scripts in web directories

Indicators Of Compromise (IOCs)

Zscaler Deception observed IP addresses delivering PHP2Shell-related payloads. Selected source IP addresses and their associated activity are listed below.

IP Address

Observed activity

169[.]58[.]138[.]154

Nuclei code-injection + deserialization check

23[.]226[.]136[.]36

OOM / memory-exhaustion trigger (CVE-2026-109618)

78[.]17[.]70[.]38

 

OS command exec + file write

135[.]136[.]21[.]120

 

Persistent webshell

81[.]17[.]100[.]107

Real deserialization RCE gadget chains (phpggc)

The full list of source IP addresses and JA4 fingerprints observed in this activity are available in the ThreatLabz GitHub repository.

Contributors: Abhishek Parikh, Deepak Keshav, Prajjwal Singh, Sayan Mitra, Nataraja Gundale, Rishabh Nihalani, Sai Nikhil Perla, Rubin Azad

form submtited
Thank you for reading

Was this post useful?

Disclaimer: This blog post has been created by Zscaler for informational purposes only and is provided "as is" without any guarantees of accuracy, completeness or reliability. Zscaler assumes no responsibility for any errors or omissions or for any actions taken based on the information provided. Any third-party websites or resources linked in this blog post are provided for convenience only, and Zscaler is not responsible for their content or practices. All content is subject to change without notice. By accessing this blog, you agree to these terms and acknowledge your sole responsibility to verify and use the information as appropriate for your needs.

Get the latest Zscaler blog updates in your inbox

By submitting the form, you are agreeing to our privacy policy.