The 2Shell family grew: after PHP, researchers demonstrated remote code execution in Node.js, with the official build as the target. The researchers’ name: Node2Shell.
The case is Imperva’s. The target was the official Node 24.22.0 image for Linux arm64, no debugger and no custom build, and the path was the Brotli decoder the runtime carries embedded, CVE-2026-111497. Node disclosed the flaw and published the fix on October 21, the same day as PHP’s emergency patch, and version 24.22.1 rejects the same data that executed code in the prior one.
How the application reaches the decoder nobody chose
The Brotli decoder exists in lines 22.x, 24.x, and 26.x, and the application reaches it through two paths almost nobody lists in inventories: reading a Brotli-compressed response through native fetch(), or receiving a Brotli request body decoded by middleware (Express 5 decodes in body parsers, alongside gzip and deflate).
A plain Node server, without middleware, does not decode on its own. But whoever uses a framework, does. And the decoder was not chosen: it came embedded in the runtime, which is the definition of attack surface a declared-package inventory does not see.
The honest calibration of the exploit
The first public proof of concept executed code only on a deliberately weakened build, and on the standard build the author reported crash and limited memory read. Imperva’s demonstration crossed that line on the official build, but needed several attempts, and no in-the-wild exploitation was reported as of October 22.
The calibration matters because it sets priority: RCE demonstrated on the official build with several attempts is this week’s fix; a proof of concept on a weakened build is a cycle fix. Both update; the urgency differs.
What to do
- Update to 24.22.1, noting that container images and artifacts embedding the Node binary need their own updates, which a declared-package inventory alone misses.
- Map out-of-support lines: 20.x and older receive no fix and stay exposed.
- Limit untrusted Brotli traffic at the edge while updates reach the fleet: Imperva and Vercel already published rules.
- Take the inventory down to the binary: container image, embedded decoder, release line, and end-of-life date.
Conclusion
The week drew the map: PHP, the kernel, and now the decoder nobody chose to install. The service’s perimeter includes what the runtime carries inside, and the inventory looking only at declared packages does not see that floor.
The 2Shell family will likely gain members, because the technique (a path into an embedded decoder with hostile data) is not runtime-specific. The defense surviving the family is the inventory descending to the binary and the edge filtering what the runtime will decode.