Node2Shell: Brotli Decoder Bug in Node.js Enables Remote Code Execution (CVE-2026-111497)

What Is Node2Shell?
Node2Shell is the name Imperva's Red Team gave to its research and proof of concept for CVE-2026-111497, a vulnerability in the Brotli decoder bundled with Node.js. The Node.js project disclosed the issue on October 21, 2026 as part of its October security releases, rating it High severity. Fixes landed for the 22.x, 24.x and 26.x release lines.
The bug lets specially crafted Brotli-compressed data trigger an out-of-bounds write in the decoder. That can corrupt process memory, crash the process, leak memory contents, or under the right conditions let an attacker execute code inside the vulnerable Node.js process.
Imperva published an independent technical analysis on October 22. Their researchers demonstrated code execution on the official Node.js 24.22.0 Linux ARM64 image without a debugger or instrumented runtime. The same inputs were rejected by the patched Node.js 24.22.1 release.
This moves the issue beyond a theoretical memory-safety problem. However, Imperva's published results cover specific configurations and do not establish that every vulnerable deployment can be exploited with the same reliability.
Recommendation: update Node.js to a fixed release, rebuild affected deployments, and restart processes running the vulnerable runtime.
Sources:
- Node.js security advisory: https://nodejs.org/en/blog/vulnerability/october-2026-security-releases
- Imperva's Node2Shell research: https://www.imperva.com/blog/node2shell-from-brotli-data-to-remote-code-execution/
What Is Brotli and Why Does This Affect Node.js?
Brotli is a compression format widely used to shrink HTTP payloads: HTML, JavaScript, JSON, API responses and more. Web servers and clients negotiate it transparently.
Node.js includes native compression and decompression through its node:zlib APIs. The runtime ships with a copy of Google's Brotli decoder. Applications can hit the vulnerable code without installing a separate Brotli package.
The key detail: the vulnerability sits below application code, in the native decoder. An application may use a high-level API or middleware while the vulnerable operation happens inside the Node.js runtime.
An application is exposed when it actually decodes Brotli data controlled by an attacker. Merely running a Node.js server does not make every incoming request vulnerable.
Two common routes into the decoder:
- Incoming request bodies: an application accepts a Brotli-compressed HTTP request body and decompresses it.
- Outgoing responses fetched by the application: an application calls
fetch()to retrieve content from another server, and Node.js automatically decompresses a Brotli-encoded response.
The second case deserves attention because the remote server supplying the response may be outside the application's control. URL previews, webhook processing, remote-content imports, and services that fetch user-supplied URLs can create this exposure.
A bare Node.js HTTP server does not automatically decompress incoming Brotli request bodies simply because they arrive over HTTP. The application or a library must invoke a decoding path.
Source: https://www.imperva.com/blog/node2shell-from-brotli-data-to-remote-code-execution/
Technical Root Cause
The problem is in the Brotli decoder's handling of an invalid block-switch operation.
Brotli streams contain block metadata telling the decoder which block types are available. During decompression, the decoder processes these blocks and switches between them when required.
A block category that declares only one available type cannot validly switch to another type. The vulnerable decoder did not handle this invalid condition correctly.
The decoder function DecodeBlockTypeAndLength() used the same false result for two different situations:
- The compressed input was incomplete and the decoder genuinely needed more data.
- The stream requested a block switch that was invalid according to the stream's own metadata.
Those conditions should not have been treated as equivalent.
On the affected decoding path, an invalid block switch could be interpreted as a request for more input instead of a permanent format error. Decoding then continued in a state that should never have been reached. Node.js's advisory describes how the streaming decoder could continue appending input bytes to an eight-byte internal buffer, causing an out-of-bounds write.
The result is memory corruption inside the process running the decoder. Depending on circumstances, that can lead to a process crash, disclosure of process memory, or code execution.
The upstream correction makes the invalid block switch produce a dedicated format error and propagates that error so the decoder stops rather than continuing with invalid state.
The upstream Brotli fix is available here: https://github.com/google/brotli/commit/0ed4268a4401abcb44720963
Node.js incorporated the fix into its security releases and exposed the associated BROTLI_DECODER_ERROR_FORMAT_BLOCK_SWITCH error constant in its zlib bindings.
Technical explanation: https://www.imperva.com/blog/node2shell-from-brotli-data-to-remote-code-execution/
What Can an Attacker Do?
The security impact can include:
Remote code execution (RCE): Under suitable conditions, a crafted Brotli stream can make attacker-supplied code execute inside the vulnerable Node.js process.
Memory disclosure: Memory corruption can expose data held in the process. Depending on the application and exploit, that could include sensitive information in memory.
Denial of service: A malformed stream can crash the process or otherwise disrupt service.
RCE is the most serious outcome because an attacker may run commands or perform actions available to the compromised process. This does not automatically mean root access or complete host control. Impact depends on the operating system, the permissions of the Node.js process, container or sandbox isolation, and other security controls.
The key prerequisite is access to a decoding path that processes attacker-controlled Brotli input. A publicly reachable Node.js service that decodes such input is a more immediate concern than a service that only decompresses data from trusted sources.
Practical risk also depends on what the compromised process can access: environment variables, application secrets, API credentials, filesystem paths, internal network services and databases.
Source: https://nodejs.org/en/blog/vulnerability/october-2026-security-releases
Which Applications and Configurations May Be Exposed?
The issue is in the runtime's Brotli decoder, so the risk is not limited to a particular framework.
Incoming HTTP request bodies
Some request parsers support Brotli-compressed request bodies. If such a parser passes attacker-controlled content to the vulnerable decoder, a remote request may trigger the bug.
Imperva tested the following configurations on Node.js 24.22.0:
- Express 5.0.0 through 5.3.0, using the tested request-parsing setups.
body-parser2.0.0 through 2.3.0, including testedraw()andjson()parsing paths.
These version ranges describe the configurations Imperva tested, not an assertion that every release in each range was individually tested. The vulnerable component is Node.js itself; these libraries provide routes into it.
Outgoing HTTP responses
Node.js's built-in fetch() can automatically decompress a Brotli-encoded HTTP response. A service that fetches content from an untrusted or attacker-controlled server can encounter the vulnerability even if it never accepts compressed request bodies from its own users.
This path matters because filtering inbound request bodies at a reverse proxy does not protect an application from malicious Brotli responses it fetches from elsewhere.
Direct compression APIs and other libraries
Application code can also use the node:zlib Brotli APIs directly. Libraries built on those APIs may reach the same vulnerable decoder.
Containers and bundled runtimes
A deployment may continue to run a vulnerable copy of Node.js even after its host operating system or package manager has been updated. Common places to check:
- Docker and other container images
- Kubernetes workloads
- CI/CD runners and build agents
- Serverless runtimes and deployment platforms
- Applications packaged with an embedded Node.js runtime or as single executable applications
- Developer machines, test environments and staging deployments
A framework version alone does not determine whether the runtime is fixed. Check the version actually running in each environment.
Sources:
- Imperva: https://www.imperva.com/blog/node2shell-from-brotli-data-to-remote-code-execution/
- Vercel security advisory: https://vercel.com/kb/bulletin/node-js-security-advisory
What Imperva Demonstrated
Imperva published its Node2Shell research on October 22, 2026.
The researchers tested fresh containers using the official Node.js 24.22.0 Linux ARM64 image. They reported successful execution of code carried through crafted Brotli data without needing a debugger or an instrumented Node.js binary.
They tested two broad routes:
- A compressed HTTP response consumed by Node.js's built-in
fetch(). - Incoming Brotli-compressed request bodies processed by the tested Express 5 and
body-parserconfigurations.
In their demonstration, the test application created a marker file after receiving and processing the crafted data, despite having no application-level code to create that file. The researchers used this to demonstrate that code supplied through the malicious data had executed inside the process.
The same inputs were rejected by Node.js 24.22.1, and the fixed test server remained running.
Important limits to these findings:
- The confirmed configuration in Imperva's published demonstration was Node.js 24.22.0 on Linux ARM64.
- The exploit did not work on every attempt.
- The published tests do not cover every Node.js build, architecture, framework version or deployment configuration.
- Imperva did not establish that every vulnerable application is equally exploitable.
These limits should not be confused with evidence that the remaining affected versions are safe. The official Node.js advisory lists all three supported release lines as affected, and Vercel reports research demonstrating memory disclosure and code execution on unpatched 22.x, 24.x and 26.x versions.
A separate public proof-of-concept report also appeared during the initial disclosure period. Details and reliability reported for different demonstrations vary. The strongest specific evidence to cite is Imperva's reproducible result against the official 24.22.0 build and its comparison with 24.22.1.
Source: https://www.imperva.com/blog/node2shell-from-brotli-data-to-remote-code-execution/
Disclosure Timeline
| Date | Event |
|---|---|
| October 21, 2026 | Node.js security releases published for 22.x, 24.x and 26.x, including the fix for CVE-2026-111497. Node.js credits OpenAI Codex Security researchers Khai Tran and Sylvie Mayer with reporting the issue. Matteo Collina and Antoine du Hamel are credited with fixing it. |
| October 22, 2026 | Imperva publishes Node2Shell write-up, demonstrating code execution against the official vulnerable Node.js 24.22.0 Linux ARM64 image. Tests confirm the same data is rejected by 24.22.1. |
| October 22, 2026 | Bun releases version 1.4.4, which includes the relevant Brotli fix among its security changes. |
| October 23, 2026 | Wider security warnings continue. NHS England Digital publishes an alert assessing future exploitation as likely now that public proof-of-concept research is available. |
Primary and related sources:
- Node.js advisory: https://nodejs.org/en/blog/vulnerability/october-2026-security-releases
- Imperva research: https://www.imperva.com/blog/node2shell-from-brotli-data-to-remote-code-execution/
- Bun 1.4.4 release: https://bun.sh/blog/bun-v1.4.4
- Bun tracking issue: https://github.com/oven-sh/bun/issues/46352
- NHS England Digital alert: https://digital.nhs.uk/cyber-alerts/2026/cc-4881
Affected Node.js Versions
Node.js has identified the 22.x, 24.x and 26.x release lines as affected. The corresponding fixed versions are:
| Release line | Fixed release |
|---|---|
| Node.js 22.x | 22.23.4 |
| Node.js 24.x | 24.22.1 |
| Node.js 26.x | 26.12.1 |
Update to the applicable fixed release or a newer patched release in the same branch. Do not assume that updating application dependencies alone will fix the problem.
These are the published fix versions in the October 21, 2026 Node.js security releases.
Official release notes:
- Node.js 22.23.4: https://nodejs.org/en/blog/release/v22.23.4/
- Node.js 24.22.1: https://nodejs.org/en/blog/release/v24.22.1/
- Node.js 26.12.1: https://nodejs.org/en/blog/release/v26.12.1/
End-of-life Node.js versions
The Node.js advisory states that end-of-life release lines should be considered affected when a security release is issued. End-of-life branches do not necessarily receive fixes.
Node.js 20 reached end of life on April 30, 2026. The older 21.x, 23.x and 25.x branches are also end of life. The recommended approach is to migrate to a supported line rather than continue relying on an old runtime.
For operating-system packages, check the relevant distribution's own security advisory. Distribution maintainers may ship backported fixes or classify particular packaged builds differently from the upstream Node.js releases. Do not infer the state of a distribution package solely from its version number.
Brotli Versions Outside Node.js
CVE-2026-111497 is also tracked as a vulnerability in Google's Brotli decoder. Security advisories describe affected upstream Brotli releases as versions 1.0.3 through 1.2.0, with fixes available in the corresponding maintained branches:
- Brotli 1.0.x: update to 1.0.10 or later in that branch.
- Brotli 1.1.x: update to 1.1.1 or later in that branch.
- Brotli 1.2.x: update to 1.2.1 or later in that branch.
Check the version and patch status supplied by the maintainer of the software that bundles Brotli. A standalone Brotli installation may have a different update path from Node.js's bundled copy.
Bun is also relevant. Its own tracking issue identified the missing upstream fix in Bun's Brotli decoder, and Bun released version 1.4.4 on October 22, 2026. Bun users should update to 1.4.4 or newer and verify the release notes for their deployment.
Sources:
- GitHub Advisory Database: https://github.com/advisories/GHSA-9v8h-qqgm-4m35
- Upstream Brotli correction: https://github.com/google/brotli/commit/0ed4268a4401abcb44720963
- Bun issue: https://github.com/oven-sh/bun/issues/46352
- Bun 1.4.4 release notes: https://bun.sh/blog/bun-v1.4.4
Severity and Scoring Differences
The Node.js project classifies CVE-2026-111497 as High severity in its security advisory.
Some third-party vulnerability databases assign more severe numerical ratings. At the time of this research, Tenable lists a CVSS 3.1 score of 9.8 and a CVSS 4.0 score of 9.2, while the Amazon Linux advisory lists a CVSS 3.1 score of 8.1 with a different attack-complexity assessment.
These are scores from different providers and scoring contexts. They should not be presented as though Node.js itself assigned all of those ratings.
For this article: Node.js rates the issue High, while some third-party databases assign higher CVSS scores. If a numerical score is included, name the scoring source and version rather than presenting a bare number as universally authoritative.
Sources:
- Node.js severity rating: https://nodejs.org/en/blog/vulnerability/october-2026-security-releases
- Tenable: https://www.tenable.com/cve/CVE-2026-111497
- Amazon Linux advisory: https://explore.alas.aws.amazon.com/CVE-2026-111497.html
- EUVD: https://euvd.enisa.europa.eu/vulnerability/EUVD-2026-108169
Has the Vulnerability Been Exploited in the Wild?
There is clear public evidence of laboratory exploitation: Imperva demonstrated code execution on a stock vulnerable Node.js build.
In the sources reviewed for this article, I found no confirmed report of exploitation against real-world victims as of October 23, 2026. That is not proof that nobody has exploited it. Security teams should distinguish confirmed incidents from laboratory demonstrations and forecasts about future attacks.
Public proof-of-concept reporting and the demonstrated exploit make future exploitation a credible concern. NHS England Digital's October 23 alert specifically assesses future exploitation as likely.
A useful way to phrase this:
Public research has demonstrated code execution against a vulnerable Node.js build, and security agencies are warning that exploitation is likely. I found no confirmed public report of in-the-wild exploitation as of October 23, 2026, but the absence of a reported incident is not evidence that an unpatched service is safe.
Source: https://digital.nhs.uk/cyber-alerts/2026/cc-4881
How to Protect Affected Systems
First priority: Upgrade Node.js
Use the fixed release for the relevant branch:
- 22.23.4 or newer in the 22.x line.
- 24.22.1 or newer in the 24.x line.
- 26.12.1 or newer in the 26.x line.
Restart running processes after updating. A running process will continue using its loaded runtime until it is restarted.
Check the runtime in production
Do not rely only on a local developer version or a package manifest. Check the actual runtime used by each deployed service, container, job and serverless function.
For a basic version check, run:
node -p process.versionRun this in the same container or environment that executes the application. Also inspect base images, deployment configurations and build pipelines for versions pinned to vulnerable releases.
An image explicitly pinned to node:24.22.0 remains based on that vulnerable release until the image reference is changed and the application is rebuilt and redeployed using a fixed version.
Review exposed Brotli decoding paths
Prioritize services that:
- Accept Brotli-encoded request bodies from untrusted clients.
- Use Express 5 or
body-parser2.x to decode request bodies. - Fetch responses from user-supplied or otherwise untrusted URLs.
- Process external webhooks, remote previews or imported content.
- Pass untrusted bytes to the
node:zlibBrotli APIs.
These checks help establish exposure and set remediation priorities. They do not replace the runtime update.
Temporary mitigation when an update cannot happen immediately
Where appropriate, a reverse proxy, WAF or application gateway can temporarily reject Brotli-compressed incoming request bodies on affected endpoints. This can reduce exposure through the inbound request path, but it does not address malicious Brotli responses that the application's own fetch() calls decompress.
Imperva and Vercel have both announced protections against known exploit patterns. Such rules can provide a layer of defense, but their coverage is limited to the traffic and patterns they inspect. They are not a substitute for a fixed runtime.
The Node.js advisory does not provide a general built-in workaround. Patching remains the main remediation.
Sources:
- Node.js: https://nodejs.org/en/blog/vulnerability/october-2026-security-releases
- Vercel: https://vercel.com/kb/bulletin/node-js-security-advisory
- Imperva: https://www.imperva.com/blog/node2shell-from-brotli-data-to-remote-code-execution/
Detection and Investigation
There is no single log entry that reliably proves exploitation.
Unexpected Node.js process exits during decompression, decoder errors and unusual traffic containing malformed Brotli streams may justify further investigation. On their own, these signs do not establish that an attacker executed code.
Teams investigating a potentially affected service should correlate the runtime version, the source of compressed input, HTTP request and response logs, application errors, process restarts, and any unexpected filesystem or process activity.
The fix introduces a dedicated Brotli decoder error for the invalid block-switch condition. That error may be useful when reviewing decoder logs from a patched runtime, although its presence only indicates that malformed input reached the decoder, not that exploitation succeeded.
The most important immediate task is to identify every vulnerable runtime and patch it. Incident-response steps should follow if logs or host-level telemetry show evidence of compromise.
Important Distinctions and Caveats
This article preserves these distinctions:
-
Node2Shell versus CVE-2026-111497: Node2Shell is Imperva's name for its research and exploit; CVE-2026-111497 is the vulnerability identifier.
-
Potential RCE versus demonstrated RCE: The vulnerability's impact includes possible remote code execution. Imperva demonstrated execution on Node.js 24.22.0 ARM64, but the published test results do not cover every possible configuration.
-
Node.js exposure versus every Node.js server: A service must reach the vulnerable decoder with attacker-controlled Brotli data. Not every HTTP request automatically invokes Brotli decompression.
-
Patch versus WAF: WAF rules can reduce exposure for inspected traffic, but cannot cover every decoding path, especially responses fetched by the application itself.
-
Severity rating versus numerical CVSS score: Node.js calls the issue High. Other databases assign different numerical scores. Attribute each rating to its source.
-
No known public incident versus no risk: A lack of confirmed public incidents is not proof that exploitation has not occurred.
-
Upstream releases versus operating-system packages: Distributions may package or backport security fixes. Check the package maintainer's advisory and the actual runtime rather than assuming every packaged version maps directly to an upstream version.
References
- Node.js security advisory: https://nodejs.org/en/blog/vulnerability/october-2026-security-releases
- Node.js release notes: https://nodejs.org/en/blog/release/v24.22.1/
- Imperva Node2Shell research: https://www.imperva.com/blog/node2shell-from-brotli-data-to-remote-code-execution/
- Upstream Brotli fix: https://github.com/google/brotli/commit/0ed4268a4401abcb44720963
- Bun 1.4.4 release: https://bun.sh/blog/bun-v1.4.4
- Vercel advisory: https://vercel.com/kb/bulletin/node-js-security-advisory
- NHS England Digital alert: https://digital.nhs.uk/cyber-alerts/2026/cc-4881
- GitHub Advisory Database: https://github.com/advisories/GHSA-9v8h-qqgm-4m35
- Tenable: https://www.tenable.com/cve/CVE-2026-111497
- Amazon Linux advisory: https://explore.alas.aws.amazon.com/CVE-2026-111497.html
- EUVD: https://euvd.enisa.europa.eu/vulnerability/EUVD-2026-108169
Research reflects the position as of October 23, 2026.
Read Next.
PHP2Shell: AI Uncovers Critical RCE Vulnerabilities in the PHP Engine
Wiz Research discloses PHP2Shell — a set of critical vulnerabilities in the PHP core engine allowing unauthenticated remote code execution and memory disclosure. The flaws affect PHP versions back to 5.4 and were discovered with significant AI assistance.
Copy Fail: Page Cache Corruption in the Linux Kernel (CVE-2026-31431)
CVE-2026-31431, dubbed 'Copy Fail,' allows local attackers to gain root privileges by corrupting the Linux page cache via the algif_aead crypto interface. This article breaks down the technical root cause and the exploitation timeline.
Dirty Frag: Memory Corruption in the Linux IPv6 Stack (CVE-2026-43500)
Dirty Frag represents a dual-CVE vulnerability in the Linux kernel network stack. By exploiting a race condition in IPv6 fragment reassembly, attackers can achieve kernel-mode heap corruption and local privilege escalation.

