Aikido

What are shell vulnerabilities? PHP2Shell, Node2Shell (HTTP2Shell), React2Shell and Log4Shell explained

Written by
Nicholas Thomson

A shell vulnerability is a remote code execution (RCE) flaw in software. The -Shell suffix took off with Log4Shell (CVE-2021-44228) in December 2021. React2Shell switched the 4 out for a 2 in December 2025, and the research community followed the naming convention when dubbing October's bugs. PHP disclosed PHP2Shell on October 21, 2026, and Node.js shipped its Node2Shell fixes the same day. Either one would have been the security story of the year on its own.

If your stack runs PHP, Node.js, React, or Java, at least one of these was probably sitting in it if you were running it a few years ago.

What do all shell vulnerabilities have in common?

Every shell vulnerability exists below the application, in a logging library, a UI framework, a language runtime, or a compression decoder. In PHP's reported demonstrated exploit against Apache with mod_php, PHP2Shell fires while PHP is still processing the incoming request, before a single line of your application runs. React2Shell reached apps that never defined a server function of their own. A team can write careful, well-reviewed code and still be exposed, because the vulnerable part isn’t something they wrote.

In all of these shell vulnerabilities, attacker-controlled input reached code that treated it as safe. Log4j interpreted text it was only meant to write down, and React rebuilt objects from Flight payloads without checking their structure. Express 5 and body-parser 2.x decode Brotli request bodies from any client that sends one, often before any authentication check runs.

None of these vulnerabilities require the attacker to log in. One crafted request is enough to get code running on the server. Node2Shell also had a second route, since a crafted response to a request your app makes can trigger it, too. 

Most teams also inherit the vulnerable component without ever choosing it. Log4j usually arrived as a dependency of a dependency, and Node.js and PHP ship inside container images that rarely get rebuilt until something forces it. Brotli goes further still, since its decoder is built into runtimes and proxies like Node.js, Bun, .NET and Envoy. In Python, popular HTTP clients such as requests and httpx load Brotli automatically when it’s present, and some packages, such as Scrapy, install it as a dependency, so an app can be exposed without importing Brotli anywhere in its own code.

Shell vulnerabilities at a glance

Vulnerability CVE Disclosed Where the bug lives Bug Severity Fixed in
Log4Shell CVE-2021-44228 December 2021 Apache Log4j 2 Java Naming and Directory Interface (JNDI) lookup injection Common Vulnerability Scoring System (CVSS) 10.0 Log4j 2.17.1 and later
React2Shell CVE-2025-55182 December 2025 React Server Components Flight protocol Insecure deserialization CVSS 10.0 React 19.2.1, or the patched release on your 19.x line
PHP2Shell CVE-2026-109618 and CVE-2026-109619 October 2026 PHP engine request handling Use-After-Free (UAF) CVSS 9.2 PHP 8.5.12, 8.4.27, 8.3.36 and 8.2.35
Node2Shell (HTTP2Shell) CVE-2026-111497 October 2026 Brotli decoder compiled into Node.js Out-of-bounds write CVSS 9.2 Node.js 22.23.4, 24.22.1 or 26.12.1 and Bun 1.4.4

Memory corruption shell vulnerabilities (PHP2Shell and Node2Shell)

PHP2Shell lives in the C code of PHP’s own engine, while Node2Shell lives in Brotli, a C compression library that Node.js and many other platforms compile into their own code. Both reached the public through AI-assisted research, though in PHP2Shell’s case the models finished a job humans had started years earlier. 

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

A PHP worker handles request after request, setting aside memory for each one and freeing it once the request is done. Both PHP2Shell bugs force PHP to run out of memory at a precise moment, so a request dies partway through its work and leaves a pointer to memory that’s already been freed. The attacker’s next request fills that memory with crafted data, and PHP reads it as one of its own internal objects. 

CVE-2026-109618 strikes while PHP is setting up request data, and CVE-2026-109619 abuses state the worker keeps between requests, with session upload progress, which is enabled by default, as one confirmed path.

The vulnerable code dates to PHP 5.4, released in 2012, and the idea behind it goes back to a memory-limit bug Stefan Esser found in 2004. A 2024 audit surfaced the same problem, but nobody could prove it was exploitable, so the fix stalled. In August 2026, Calif researcher Ryan Austin used AI to do what the audit couldn’t and turned the bug into working code execution.

Details leaked ahead of the planned disclosure, PHP shipped fixes a day early on October 21, and Cloudflare reported that exploitation had started the same day. Our PHP2Shell advisory covers affected versions, mitigations and how to patch, and we keep it updated as guidance changes.

Node2Shell (CVE-2026-111497)

Node.js bundles its own copy of Brotli, Google’s compression library, and Node2Shell is a bug in Brotli’s decoder where crafted compressed data makes it write past the end of a memory buffer. 

OpenAI’s Codex Security team reported it as remote code execution that works in both directions, so a malicious client can take over an unpatched server and a malicious server can take over an unpatched client that accepts compressed responses. In Node.js, Express 5 and body-parser 2.x decode Brotli request bodies automatically, and fetch() does the same for responses.

Researchers got code execution on an unmodified Node.js 24.22.0 image, but their exploit didn’t work on every attempt, so a crash or a memory leak is the more likely outcome in practice. Our Node2Shell advisory lists the fixed versions for each release line.

HTTP2Shell and Broccoli2Shell 

Tweet saying any application that sends HTTPS requests to destinations over the internet are affected by HTTP2Shell

Brotli’s decoder ships inside far more than Node.js, which is why the same bug picked up names like HTTP2Shell and Broccoli2Shell (HTTP2Shell and Broccoli2Shell refer to the same Brotli bug from Node.js). Patches are now out for Node.js, Bun, Envoy, Istio, .NET, Python, Java brotli4j, libbrotli, Ubuntu and several Linux distributions, while SUSE and the standard Red Hat Enterprise Linux repositories don’t have a fix yet.

Brotli’s maintainers had already fixed the bug in their source code on February 27, but nobody recognized it as a security issue, so it never made it into a release until October 21. Projects bundle released versions of Brotli, so every copy in the wild stayed vulnerable for eight months, and each project then had to ship its own update on its own schedule. Aikido Security tracks each one in a live patch-status table.

Logic 2Shell vulnerabilities (Log4Shell and React2Shell)

Log4Shell and React2Shell happened in Java and JavaScript, languages that manage memory for you, so nothing gets corrupted. The flaws sit in how a feature was designed, which let an attacker’s input decide what code the server runs. Both earned a perfect CVSS 10.0 🏆.

Log4Shell (CVE-2021-44228)

Log4j is a Java logging library, and Log4j 2 supported lookups, placeholders written as ${...} that it swapped for a real value, like an environment variable, whenever it wrote a message. It did this for any text it logged, including text from users. One lookup type, ${jndi}, tells Java to fetch an object from a directory server, so an attacker who slipped a ${jndi} lookup pointing at their own server into a browser header or a Minecraft chat message could make Log4j download a Java class and run it.

Most apps log some user input, which made almost any text field on the internet a possible way in. Log4j also tended to sit several layers deep in dependency trees, so many teams spent the first days just working out whether they ran it. Researchers then found holes in the first fix (2.15.0) and the one after it, and teams kept upgrading until 2.17.1 closed them off.

React2Shell (CVE-2025-55182)

React Server Components run on the server and send their output to the browser, and the browser can call server functions directly. React carries all of this back and forth in a format called Flight. When a Flight request arrives, the server turns it back into objects, a step called deserialization, and React trusted the structure of that data. An attacker could shape a request that reached built-in Node.js functions like child_process.execSync and ran shell commands without logging in.

Apps were exposed even if they never defined a server function, because the Flight decoding code runs whenever Server Components are supported. Default React 19 setups were vulnerable, and CISA, the US Cybersecurity and Infrastructure Security Agency, added it to its list of vulnerabilities exploited in real attacks. A follow-up bug, CVE-2025-67779, got around the original patch, so teams had to upgrade a second time.

Why 2Shell bugs keep showing up

PHP2Shell, Node2Shell, and HTTP2Shell arrived in the same week as critical bugs in eMudhra, GitLab, NGINX, Plex, Railway and OpenCode. Any one of them could have been the biggest security story of the year, and people started calling it Black October.

AI is finding old bugs faster

PHP has powered a large share of the web for three decades, so most people assumed its serious bugs were found long ago, yet PHP2Shell sat in the code for 14 years. After the disclosure, we pointed Aikido’s AI code analysis at PHP’s source and it rediscovered PHP2Shell within a few hours. If a defender’s tool can find a bug like this in an afternoon, attackers’ tools won’t be far behind.

How Aikido Security helps you manage 2Shell vulnerabilities

Aikido Security’s software composition analysis (SCA) and container image scanning show which repos and images still run a vulnerable runtime or library, transitive Brotli packages included.

If you can’t upgrade right away, free patched Aikido Images on Aikido’s public Amazon Elastic Container Registry cover PHP 5.5 through 8.5, apart from 8.0 and 8.1 for now. On release lines with no upstream fix, they backport the fixes so you keep your version number. For the Brotli flaw, Aikido’s patched Node.js and Ubuntu images let you stay on your current version on platforms with no vendor fix, including Node.js 18 and 20.

The free PHP2Shell checker tests a public URL and tells you where it stands, from vulnerable to fully patched. 

{{walkthrough}}

‍

Share:

https://www.aikido.dev/blog/what-are-shell-vulnerabilities

Subscribe for news

4.7/5
Tired of false positives?

Try Aikido like 100k others.
Start Now
Get a personalized walkthrough

Trusted by 100k+ teams

Book Now
Scan your app for IDORs and real attack paths

Trusted by 100k+ teams

Start Scanning
See how AI pentests your app

Trusted by 100k+ teams

Start Testing

Get secure today,
quickly and for free.

Secure your code, cloud, and runtime in one central system.
Connect a repo to discover what the reasoning agents find in your codebase.

No credit card required | Scan results in 32 seconds.
Trusted by 150k+ orgs