❌

Visualização de leitura

Stopping Node2Shell: How SentinelOne Protects Customers From Brotli-Based Remote Code Execution

Executive Summary

On October 21, 2026, the Node.js project released security updates that fix CVE-2026-111497, an out-of-bounds write in the Brotli decoder bundled with the runtime. Vendors have labeled the vulnerability Node2Shell, Brotli2Shell, Broccoli2Shell, and HTTP2Shell, because the flaw sits in Google's Brotli library and reaches software well beyond Node.js. Any application that decompresses attacker-controlled data with a vulnerable Brotli library could be at risk. Google, as the CVE Numbering Authority, scored it 9.2 under CVSS v4.0, and Node.js rates it high.

CISA added CVE-2026-111497 to its Known Exploited Vulnerabilities (KEV) catalog on October 27, 2026, with a November 10, 2026 deadline for federal civilian agencies. The public telemetry we reviewed shows exploitation attempts against honeypot sensors, and researchers have demonstrated code execution in lab environments. As of October 29, 2026, we are not aware of a public report of a confirmed compromise of a production system.

This report details Node2Shell's mechanism, affected versions, and observed activity, and outlines how SentinelOne customers and partners can strengthen their defenses.

Key Highlights

  • One flaw, many patches. Node.js, Google Brotli, Bun, .NET, Python, Envoy, Istio, and PHP for Windows each shipped their own fix. Updating one does not update the others.

  • Attempts are confirmed. Production compromise is not. ELLIO and Previdian have each recorded an exploitation attempt against their honeypot sensors. Previdian notes that such observations do not show the target was vulnerable or that the attempt succeeded.

  • A default Node.js server is not exposed by itself. Something must hand attacker-controlled Brotli data to the decoder. Node.js names direct node:zlib use. Express 5 request bodies and built-in fetch() responses reach the same decoder, and Imperva reproduced both in the lab.

  • A failed exploit still costs you. The Node.js advisory lists a crash as an outcome, and Sysdig reports that crashes have been easy to reproduce. Repeated crashes are a denial of service against any service that decodes attacker-influenced Brotli.

  • The fix was visible for nearly eight months before release. Google committed it on February 27, 2026, with no release and no advisory. End-of-life Node.js 20, 23, and 25 are not expected to receive a fix.

Organizations should take the following steps immediately:

  • Upgrade Node.js to 22.23.4, 24.22.1, or 26.12.1, then restart processes and rebuild container images.

  • Inventory every other runtime and library that embeds the Brotli decoder, and patch internet-facing services first.

  • Where patching must wait, reject inbound requests that carry Content-Encoding: br at the proxy or load balancer.

What is Node2Shell

Node2Shell is a memory corruption flaw in the Brotli decoder, the code that expands Brotli-compressed data. A Brotli stream signals switches between block types. When a stream declares only one block type, a switch is invalid and the decoder should reject it. The vulnerable decoder instead reported the invalid switch as a request for more input. The caller supplied more bytes, and the decoder kept appending them to an eight-byte internal buffer and wrote past its end, according to the Node.js advisory.

Node.js lists the outcomes as a crash, disclosure of process memory, or remote code execution, and the CVE record describes the attacker as unauthenticated. Imperva demonstrated code execution on the official Node.js 24.22.0 arm64 image. Microsoft describes the .NET impact as information disclosure, denial of service, or elevation of privilege.

Node2Shell at a Glance

Attribute

Detail

CVE

CVE-2026-111497, also called Brotli2Shell, Broccoli2Shell, and HTTP2Shell

Weakness

Unchecked return value (CWE-252) leading to an out-of-bounds write (CWE-787). No authentication required.

Severity

CVSS v4.0 9.2 (Google, CNA). Node.js: high.

Affected Component

Google Brotli 1.0.3 through 1.0.9, 1.1.0, and 1.2.0, bundled or linked by many products

How Attacker-Controlled Brotli Reaches the Decoder

Path

Condition

Inbound request bodies

Routes that use express.json(), express.urlencoded(), express.text(), or express.raw() in Express 5 or body-parser 2 decompress bodies sent with Content-Encoding: br by default. Any client can send one.

Outbound responses

Built-in fetch() decodes Brotli automatically, so a malicious or compromised server can target the client.

Direct calls

Applications that pass untrusted input to zlib.brotliDecompress() or zlib.createBrotliDecompress().

Disclosure Timeline

Date (2026)

Event

February 27

Google commits the upstream fix with no release and no advisory.

October 21

Node.js discloses CVE-2026-111497. Google releases Brotli 1.0.10, 1.1.1, and 1.2.1.

October 22

Imperva demonstrates code execution on arm64. CVE record is published.

October 25

Microsoft releases out-of-band .NET security updates.

October 27

CISA adds the CVE to the KEV catalog.

Exploitation in the Wild

Exploitation attempts have been recorded, but a successful attack on a production system has not been publicly reported as of October 29, 2026. CISA added CVE-2026-111497 to its KEV catalog on October 27, 2026, with a November 10, 2026 deadline for federal civilian agencies under BOD 26-04.

The public telemetry comes from honeypots. Two threat intelligence providers each recorded an attempt: ELLIO saw a request built for Node.js 24.22.0 on x86-64 on October 26, and Previdian saw one from a U.S.-based address on October 27. Previdian notes that such observations do not show the target was vulnerable or that the attempt succeeded.

Researchers have reproduced code execution only in lab testing. Imperva ran code on the official Node.js 24.22.0 arm64 image through fetch() and Express 5 request bodies, needed multiple attempts, and did not test every Node.js build. Public proof-of-concept code appeared within hours of the October 21 release, according to Sysdig, so organizations should expect further attempts, particularly against internet-facing Express 5 services.

Observed Indicators

Type

Indicator

IP Address

94[.]154[.]43[.]7

SHA-256

7fcbdaaecd4419e2930927844f3b772668204737a4e7602a2290c991c93c5c4b

Behavior

A Node.js process that starts or becomes a shell

Patch Status

Node.js has fixed every supported release line: 22.x, 24.x, and 26.x. It will not patch end-of-life lines, which the project says are always affected when a security release occurs. Organizations running Node.js 20, 23, or 25 have no patch to apply and must upgrade to a supported line.

Product

Affected Version

Fixed Version

Node.js

22.x before 22.23.4, 24.x before 24.22.1, 26.x before 26.12.1

22.23.4, 24.22.1, 26.12.1

Node.js 20, 23, 25

All versions

No fix. Move to a supported line

Google Brotli

1.0.3 through 1.0.9, 1.1.0, 1.2.0

1.0.10, 1.1.1, 1.2.1

Bun

1.0.21 through 1.4.3

1.4.4

Microsoft .NET

8 before 8.0.33, 9 before 9.0.22, 10 before 10.0.14, 11 before RC3. Exposed only where Brotli decompression is in use. .NET Framework is not affected.

8.0.33, 9.0.22, 10.0.14, 11 RC3

PHP for Windows

Builds that bundle Brotli 1.0.3 through 1.2.0

8.2.35-1, 8.3.36-1, 8.4.27-1, 8.5.12-1

Python Brotli, brotlicffi

Bundled Brotli 1.0.3 through 1.2.0 (brotlicffi up to 1.2.0.2)

Brotli 1.2.1, brotlicffi 1.2.1.0

Envoy Proxy

1.36.11, 1.37.7, 1.38.5, and 1.39.2

1.36.12, 1.37.8, 1.38.6, 1.39.3, 1.40.0

Istio

1.29.x before 1.29.9, 1.30.x before 1.30.6, 1.31.x before 1.31.2

1.29.9, 1.30.6, 1.31.2

Recommended Mitigations

Patch, Restart, and Rebuild

  • Upgrade to a fixed Node.js release, update every Dockerfile that pins an older tag, and restart or redeploy every workload.
  • Confirm patch status from the Node.js release version running in each workload, not a bundled library version string, which may not reflect a backported fix.

Find Every Copy of the Decoder

  • Inventory Bun, .NET, Python Brotli, Envoy, Istio, PHP for Windows, and statically built executables, including staging, CI, build images, and developer machines.
  • Where Node.js links the system Brotli library, as it does on Debian, check your distribution’s advisory for the Node.js package as well as brotli. Debian’s tracker lists both.
  • PHP for Windows fixed the flaw with rebuilt packages that keep the same PHP version number, so php -v looks the same before and after. Check the -1 build suffix or the SHA-256 on the download page.
  • Move off Node.js 20, 23, and 25 on a defined date.

Reduce Exposure Until Patching Finishes

  • Reject requests with Content-Encoding: br at the WAF or proxy, or set the body-parser inflate option to false so compressed bodies return HTTP 415. The second option also rejects gzip and deflate bodies, so test client traffic first.
  • Restrict server-side fetches to trusted destinations. Link previews, webhooks, and crawlers send attacker-influenced URLs into fetch(), and removing br from Accept-Encoding does not stop a hostile server from replying with Brotli.
  • Enable a vendor WAF rule as a stopgap where one exists. It does not replace the upgrade.

Limit the Blast Radius

  • Run Node.js services as a non-root user and limit outbound connections from Node.js hosts. Docker runs containers as root by default, and the official node image provides a node user (uid 1000) that you must select with USER or -u.

Watch for Failed Attempts

  • Alert on repeated worker crashes after requests with Content-Encoding: br. Where core dumps are enabled, restrict who can read them and shorten retention, because a core file can hold memory contents from other users’ sessions.

How SentinelOne Protects You

Node2Shell exploits the Brotli decoder inside the Node.js process. Patching Node.js and every other copy of the Brotli decoder remains the primary control. SentinelOne provides detection and visibility into post-exploitation behavior while that work is underway.

The Singularity agent builds a storyline of process activity on a host, including the Node.js services targeted by Node2Shell. These processes have a predictable life: they answer requests, call APIs, and read files. They do not normally start /bin/sh, run reconnaissance commands, download executables into /tmp, or open connections to arbitrary hosts. Behavioral detection looks for that deviation from normal behavior. 

Detection in Singularity AI SIEM

Platform detection content looks at what happens on the host after exploitation, not at the request body. 

Attacker Step

Telemetry

Visible Indicators

Code execution in the service

Process creation

Shell processes whose lineage or prior image is node, nodejs, or bun, including an in-place exec, followed by enumeration utilities (id, whoami, uname, hostname) or sensitive file reads

Tooling download

Process creation, File creation

Downloaders (curl, wget, interpreters) fetching to world-writable paths, and executables written and then run from /tmp

Files written by the service

File creation

A Node.js service account writing new executables or scripts outside its normal application paths

Shell and C2

Process creation, IP Connect

Shell processes with a socket as standard input or output, socket-redirection patterns (/dev/tcp, nc, socat), and unexpected outbound connections from Node.js service accounts

Novel child process

First-seen analytics

A Node.js process that starts or becomes a shell or image it has never run in that environment

Correlation rules tie these together. A request to the service, or an outbound fetch to an untrusted host, followed by a process spawn or file drop from the same Node.js process is the shape of a successful chain. 

Visibility at the Edge

Sysdig reports that the crash is easy to reproduce, which makes repeated worker crashes and restarts a useful early signal. Web server, WAF, and CDN logs may show requests with Content-Encoding: br followed by bursts of HTTP 5xx responses and unexplained worker restarts. Singularity AI SIEM can ingest those sources alongside endpoint data if you forward them. 

Hunt with Purple AI While You Patch

Patching is the only complete fix. While that work runs, analysts can ask Purple AI questions such as:

  • Show me shell processes whose parent or prior image was node, nodejs, or bun since October 21.
  • Show me new executable files written by the Node.js service account since October 21.
  • Show me outbound connections from the Node.js service account to destinations we have never seen.
  • Show me hosts with a spike in 500 responses followed by a Node.js process restart.

The last question depends on web server logs being ingested. 

Confirm Agent Saturation on Node.js Hosts

Confirm the agent is deployed, healthy, and in protect mode on every server and container host that runs Node.js, Bun, or another service that decompresses Brotli. Start with internet-facing Express 5 services and services that fetch external URLs.

Disclaimer

Information contained herein is current as of October 29, 2026, and is subject to change as patch releases and threat activity evolve. Recipients should not rely solely on this report for security decisions and should consult with their security teams and SentinelOne account representatives for current guidance.

Stopping PHP2SHELL: How SentinelOne Protects Customers From This Attack Technique

Executive Summary

On October 21, 2026, the PHP project released versions 8.5.12, 8.4.27, 8.3.36, and 8.2.35 to fix two critical vulnerabilities, CVE-2026-109618 and CVE-2026-109619, both rated CVSS v4.0 9.2. The two flaws are known together as PHP2Shell. They were disclosed by the security firms Calif and Wiz and by OpenAI, working with the PHP security team, after AI-assisted auditing turned an out-of-memory weakness that a 2024 audit had flagged but could not prove exploitable into working remote code execution.

Both vulnerabilities sit in PHP's memory management and error handling, code that nearly every request touches, and the earliest affected path dates to PHP 5.4.0. An unauthenticated attacker can execute code on the web server or read its process memory, including passwords, tokens, and API keys belonging to other requests. On Apache with mod_php, the attack runs before any application code executes, which means an application with no bugs of its own is still exposed. As of October 21, 2026, no verified proof-of-concept code is available publicly. Attack attempts have been observed by Cloudflare after the leak, but no confirmed in-the-wild compromise has yet been reported.

While upgrading every PHP runtime remains the primary control, SentinelOne agent detects attackers’ post-exploitation activities. Once an attacker has code execution on the web server process, the behavior that follows web server flaws: execute shell commands, drop and invoke webshells, download and execute custom payloads and outbound connections. On managed hosts, the Singularity™ agent and Singularity AI SIEM detection content look for such behaviors, and Purple AI® can be used to hunt for it during the patching window. The separate memory-disclosure path runs no code on the host, so it leaves no process behavior to detect; that path is instead surfaced through web server, WAF, and CDN telemetry forwarded into AI SIEM.

This report details PHP2Shell's mechanism, affected versions, and confirmed activity, and outlines how SentinelOne customers can strengthen their defenses.

Key Highlights

  • The flaw is in PHP itself, not in any application. WordPress, Drupal, Joomla, Magento, Laravel, and other web applications are all exposed on an affected PHP version, because the vulnerable code is in the runtime beneath them.
  • The patch is the only complete fix. PHP states plainly that no configuration change fully closes the vulnerability. Every interim mitigation reduces one attack path and leaves others open.
  • The unauthenticated path runs before your code does. On Apache with mod_php, a single crafted HTTP request triggers the flaw during request startup, so application-level controls never see it. PHP assesses the risk as highest for mod_php.
  • Memory disclosure leaks secrets without a shell. One path reads live worker memory and returns passwords, tokens, API keys, and certificates with no code execution, which makes it quieter than a shell and harder to catch with execution-focused tooling.
  • End of Life PHP will not get a patch. Organizations running PHP 8.1 and prior will not receive an official release. Source-only backports exist for 7.4, 8.0, and 8.1, and distribution or LTS vendors may offer fixed packages.
  • Leverage SentinelOne platform post-exploitation coverage. The detection by the agent is agnostic to the vulnerability and exploit chain and focuses on attackers activity following the exploit, including but not limited to, installation and usage of webshells, command executions and outbound connection behavior that follows the code execution.

Organizations should take the following steps immediately:

  • Update every PHP runtime to a fixed version and restart Apache, PHP-FPM, and any long-running workers.
  • Inventory internet-facing PHP, including the copies bundled inside appliances, control panels, and vendor software.
  • Isolate end-of-life PHP (8.1 and older) from the internet until it can be upgraded.
  • Rotate credentials, tokens, and keys that a PHP worker could hold in memory on any exposed, unpatched system.
  • Monitor the official PHP changelog for relevant updates

What is PHP2SHELL

PHP2Shell is a family of memory-safety vulnerabilities in core PHP, grouped under two CVEs that share one root cause. When PHP hits a fatal condition such as exhausting its configured memory limit, it does not unwind cleanly. It abandons the current operation with a “longjmp” out of the C call stack, so no cleanup runs and nothing records that a data structure was left half-built. A later cleanup routine, or a later request, then trusts that state.

CVE-2026-109618 is the out-of-memory case. PHP marks request data as valid before allocating memory for it. If that allocation hits the memory limit and fails, the entry is left pointing to uninitialized heap memory. When the failed request runs its cleanup routine, it processes these stale bytes, leading to corruption.. 

CVE-2026-109619 is the stale-state case. When a fatal error occurs, PHP fails to clean up properly, leaving a global pointer pointing to memory that has already been freed. Because worker processes handle multiple requests, a subsequent request on the same worker can interact with this freed memory before initialization resets it – resulting in a use-after-free condition. Session upload progress (enabled by default) is a confirmed trigger for this behavior.

Both flaws were discovered through AI-assisted auditing under OpenAI's “Patch the Planet” program. Calif and OpenAI independently reported the root cause to the PHP security team on August 11, 2026, and Wiz reported additional attack vectors on August 24, 2026. PHP first saw signs of the underlying out-of-memory problem during a 2024 audit by OSTIF and Quarkslab, but no exploitation path was proven at the time and the fix stalled. The PHP Foundation has since described that delay as a structural failure in its security process.

On October 20, the two CVE identifiers leaked on social media. PHP released a patch on October 21, 2026.

PHP2SHELL at a Glance

Attribute

Detail

Tracking

CVE-2026-109618, CVE-2026-109619 (PHP2Shell)

Vulnerability Class

Memory safety: use-after-free and improper handling of exceptional conditions (CWE-416, CWE-755)

Severity

CVSS v4.0 9.2, Critical, for both CVEs

Affected

PHP 5.4.0 through the release before each branch's fix. Nearly every version released in a decade is affected by at least one issue

Attack Vector

Unauthenticated, network, over a single crafted HTTP request

Impact

Remote code execution as the web worker, or disclosure of sensitive process memory

Exploitation Status

As of October 21, 2026: no verified proof-of-concept code is available publicly, attack attempts observed by Cloudflare after the leak, no confirmed in-the-wild compromise reported.

Affected and Fixed PHP Versions

PHP Branch

Vulnerable

First Fixed Release

8.5

< 8.5.12

8.5.12

8.4

< 8.4.27

8.4.27

8.3

< 8.3.36

8.3.36

8.2

< 8.2.35

8.2.35 (branch reaches end of life December 31, 2026)

8.1 and older

All releases

No official fix. Source backports only for 7.4, 8.0, and 8.1

Affected and Fixed PHP Versions

PHP Branch

Vulnerable

First Fixed Release

8.5

< 8.5.12

8.5.12

8.4

< 8.4.27

8.4.27

8.3

< 8.3.36

8.3.36

8.2

< 8.2.35

8.2.35 (branch reaches end of life December 31, 2026)

8.1 and older

All releases

No official fix. Source backports only for 7.4, 8.0, and 8.1

Am I Affected?

Assume exposure for any PHP runtime below the fixed version for its branch. Check the version the web server actually loads, which can differ from the command-line version, using php --version for the CLI and the equivalent for PHP-FPM or the Apache module. Linux distributions and LTS vendors received the patch in advance, and a packaged build may carry the fix under an older version number, so confirm against your vendor's advisory rather than the version string alone.

PHP states that all installations serving web requests are at risk, including PHP-FPM, Apache with mod_php, php-cgi, FrankenPHP, and LiteSpeed, and rates the risk highest for mod_php. Do not use configuration to rule out exposure. PHP validated mod_php code execution with default input and memory limits, and states that no configuration change is a complete mitigation. OpenAI has published a PHP version checker, which should be reviewed before you run it.

How The Two CVEs Differ

CVE-2026-109618

CVE-2026-109619

PHP title

RCE via OOM corruption

RCE via stale global state

Trigger

Out-of-memory during request startup, such as multipart parsing

A fatal error, including out-of-memory or an execution timeout, that leaves request state published

Requests needed

One. The invalid state is processed during the same request's shutdown

Two. One request poisons the worker, a later request on the same worker consumes the stale state

Confirmed code execution

mod_php with default PHP input and memory limits. PHP-FPM is susceptible by source analysis, with no complete exploit demonstrated

mod_php through the PHP 8.5 fatal backtrace and session upload progress paths. PHP-FPM through session upload progress, which needs a suitable application operation

Interim setting

memory_limit=-1 set administratively, plus a low post_max_size

session.upload_progress.enabled=0, and fatal_error_backtraces=0 on PHP 8.5

Limit of the setting

Partial. An underlying allocation failure can still reach the vulnerable path

Partial. Blocks the confirmed paths only

Why This Matters

A flaw in PHP itself reaches far further than a flaw in any one application. PHP is widely used across the internet, and it is embedded in content management systems, control panels such as cPanel and Plesk, and a variety of vendor applications. The hard part of this response is not applying the patch. It is finding every runtime that needs it.

The patch is also the only complete fix, and a large share of PHP cannot receive it. PHP 8.1 and older are at end of life, and Talos estimates from open-source data that around half of internet-facing PHP runs on branches with no official update. Those systems need to be upgraded to a supported branch or taken off the internet, not merely reconfigured.

Exploitation is also hard to see. The memory-disclosure path returns secrets from live worker memory without running code at all, which Wiz notes makes it harder to catch with tools focused on malicious code execution. Because the flaws execute below the application layer, Wiz also reports that application logs may contain little context, and the clearest traces are in web server and PHP error logs rather than in application telemetry.

Attack Chain

Stage 1: Reaching the Flaw Over an Unauthenticated Request

The attacker sends a crafted multipart HTTP request that places PHP's memory under pressure or forces a fatal error during request startup. A chunked or lengthless request slips past the post_max_size check, and empty file controls with deeply nested field names expand a small request body into large internal allocations.

Stage 2: Corrupting Worker State

The forced out-of-memory condition or fatal error interrupts PHP in a context that does not account for the early exit. For CVE-2026-109618, Apache with mod_php runs its request shutdown unconditionally and processes the partially initialized state as if it were valid. For CVE-2026-109619, a global pointer is left referring to freed request memory, and a later request on the same worker consumes it.

Stage 3: Code Execution or Memory Disclosure

With the heap arranged to reclaim the freed or invalid memory with attacker-controlled bytes, the corrupted state becomes a memory-corruption primitive that yields code execution as the web worker. PHP confirmed complete remote code execution against mod_php with default input and memory limits. On a separate path, the attacker instead reads live worker memory and extracts passwords, tokens, API keys, and certificates belonging to other requests, returned through the PHPSESSID response cookie, with no code execution at all.

Stage 4: Post-Exploitation

Code runs with the privileges of the web server worker, commonly www-data. From there, operators drop a web shell into the web root, spawn shells and tooling such as sh, bash, python, curl, and wget, and move laterally using any credentials recovered through memory disclosure.

Hardening Recommendations

These steps apply to any PHP estate, independent of security vendor. Patching is the only complete remediation. Everything else reduces exposure during the window before every runtime is updated.

Patch Every PHP Runtime and Restart Workers

  • Update to PHP 8.5.12, 8.4.27, 8.3.36, or 8.2.35, or to the fixed package from your Linux distribution or hosting provider.
  • Restart Apache, PHP-FPM, and every long-running PHP worker after updating. The running process keeps the vulnerable code until it is restarted.
  • Remember that updating an application, CMS, or framework does not update the PHP runtime beneath it.

Assess Your Exposure

  • Inventory every PHP runtime: web servers first, then vendor appliances, Windows software that bundles php.exe or php-cgi.exe, control panels such as cPanel and Plesk, and any WordPress, Drupal, Joomla, or Magento install.
  • Isolate end-of-life PHP (8.1 and older) behind a VPN or take it off the internet until it is upgraded to a supported branch.

Apply Interim Settings Only as a Bridge

  • For CVE-2026-109618, set memory_limit=-1 administratively so applications cannot override it, and keep post_max_size low. Do not substitute RLIMIT_AS or RLIMIT_DATA, which can trigger the vulnerable path.
  • For CVE-2026-109619, set session.upload_progress.enabled=0, and on PHP 8.5 set fatal_error_backtraces=0, applied before request parsing and followed by a worker restart.
  • Treat all of these as partial. PHP confirms there is no complete configuration mitigation, and hiding diagnostics with error_reporting, display_errors, or the @ operator does not help.

Constrain the Request at the Edge

  • At the proxy or web application firewall, enforce limits on decoded request size, input field count, multipart part count, header count per part, and nesting depth, including requests that arrive without a usable Content-Length.
  • Enable your WAF or reverse proxy vendor's managed rules for PHP2Shell, which several vendors published on October 21, and test first because rules can block legitimate traffic.
  • Treat the WAF as a layer, not a fix: Cloudflare saw attackers mutating payloads to bypass its rules.
  • If an application does not use multipart form data, block multipart requests to it before they reach PHP.

Limit Worker Reuse and Blast Radius

  • Lower PHP-FPM pm.max_requests so workers recycle more often, reducing how long the corrupted state can persist.
  • Use a cgroup memory.max as an availability boundary that kills only the affected worker, not the whole pool.
  • Apply SELinux or AppArmor policies to restrict what a web worker can execute.

Rotate Secrets Reachable in Process Memory

  • Assume any credential, session token, API key, or certificate held by a PHP worker on an exposed, unpatched system may have been disclosed.
  • Rotate them now rather than after confirmed compromise, because memory disclosure leaves little trace.

Hunt for Post-Exploitation

  • Review the web root for newly created files and web shells, and watch for new cron jobs, scheduled tasks, and accounts.
  • Alert on PHP worker processes (php-fpm, php-cgi, httpd, apache2, w3wp) spawning shells, interpreters, or download tools, including cmd.exe and powershell.exe on Windows.
  • In web server and PHP error logs, look for unusual multipart requests followed by memory-limit fatal errors or repeated HTTP 500 responses, and for unexplained PHP worker churn (Wiz).
  • Check response headers for unexpectedly large or malformed PHPSESSID cookies, which Wiz identifies as a sign of the memory-disclosure path.
  • Enable log_errors, a working error_log, and error_reporting=E_ALL in startup configuration for an isolated audit, as PHP recommends, and treat a clean log as supporting evidence rather than proof of safety.
  • Treat these signals as leads, not verdicts. They come from public research rather than confirmed attack traffic, and memory-limit errors and HTTP 500s also occur on healthy systems.

How SentinelOne Protects You

PHP2Shell executes inside the web server worker process, below the application. SentinelOne’s visibility begins where that worker runs on a host with the agent installed. The agent cannot see internal application activity which doesn’t interact with the OS or other processes as the memory-disclosure path. What SentinelOne can address is the behavior of the code executed by the attacker.

The Behavior After Exploitation

Code execution through a web server worker process has the worker’s privileges. From there the sequence is familiar. The attacker runs host and user discovery, pulls a second-stage payload with a built-in download utility, writes a web shell into the document root so a fragile memory bug does not have to be triggered twice, opens an outbound connection to attacker infrastructure, and reads application configuration files for database credentials.

Detection on the Host

The Singularity agent builds a storyline of every process group activity on a host, including the web server workers PHP2Shell targets. These workers have a predictable life: they answer HTTP requests. They do not normally start /bin/sh, run reconnaissance commands, download executables into /tmp, write new .php files into the web root, or open outbound connections to arbitrary hosts. Behavioral detection looks for that deviation from the worker’s normal behavior. With the policy mode set to protect, the agent can terminate the process tree and quarantine dropped artifacts. 

Detection in Singularity AI SIEM

Platform detection content looks at what happens on the host after exploitation, not at the request body.

Attacker Step

Telemetry

Visible Indicators

Code execution in the worker

Process creation

Web server and script-interpreter processes spawning system shells, enumeration utilities (id, whoami, uname, hostname), or sensitive file reads

Tooling download

Process Creation, File Creation

Downloaders (curl, wget, interpreters) fetching to world-writable paths, and executables written and then run from /tmp

Webshell drop

File creation

Web server processes writing .php, .jsp, .sh, or other script files into web-served directories, correlated with the inbound HTTP connection that preceded it

Reverse shell and C2

Process Creation, IP Connect

Shell processes with socket-redirection patterns (/dev/tcp, nc, socat) and unexpected outbound connections from web workers

Novel child process

First-seen analytics

A PHP or web server process spawning a child it has never spawned in that environment

Correlation rules tie these together. An inbound HTTP connection followed by a file drop or process spawn from the same worker is the shape of a successful PHP2Shell chain. 

Visibility at the Edge

The memory-disclosure path never starts a process, so host telemetry alone will not see it. It can leave traces in web server, WAF, and CDN logs: unusual multipart requests followed by memory-limit errors or bursts of HTTP 500s, malformed or oversized PHPSESSID cookies, and unexplained worker churn. Singularity AI SIEM can ingest those sources alongside endpoint data if you forward them. Existing content covers allowed web shell uploads, successful POSTs to server-side scripts that have never received them before, and web shell command execution at the network layer. 

Hunt with Purple AI While You Patch

Patching is the only complete fix, and the Hardening section covers interim settings. While that work runs, analysts can ask Purple AI questions such as:

  • Show me web server workers that spawned a shell in the last 72 hours.
  • Show me new files written to web roots by php-fpm.
  • Show me hosts with a spike in 500 responses followed by a child process from Apache.
  • Show me outbound connections from www-data to destinations we have never seen.

The 500-response question depends on web server logs being ingested. 

Confirm Agent Saturation on Web-Facing Servers

Confirm the agent is deployed, healthy, and in protect mode on every server that serves PHP, including internet-facing Linux hosts.

Conclusion

The exploitation picture for PHP2Shell is moving quickly. As of October 21, 2026, no verified proof-of-concept code is available publicly. Attack attempts have been observed by Cloudflare after the leak, but no confirmed in-the-wild compromise has yet been reported. SentinelOne is monitoring PHP2Shell activity and will update this report as exploitation evidence, vendor guidance, and detection content change.

SentinelOne recommends customers follow vendor guidance and prioritize patching as the primary defensive tactic. Interim settings, WAF rules, and detection reduce risk while it is deployed. Update every PHP runtime to 8.5.12, 8.4.27, 8.3.36, or 8.2.35, restart the workers, and confirm the fix is running on the version the web server actually loads. Move PHP 8.1 and older to a supported branch or off the internet, and rotate any secrets that a worker on an unpatched, exposed system could have held in memory.

SentinelOne Black October Webinar

Disclaimer

Information contained herein is current as of October 21, 2026, and is subject to change as patch releases and threat activity evolve. Recipients should not rely solely on this report for security decisions and should consult with their security teams and SentinelOne account representatives for current guidance.

❌