Node2Shell: Taking Over a Server with a Single Compressed Data File (CVE-2026-111497)
Overview
CVE-2026-111497, disclosed in October 2026, is an out-of-bounds write vulnerability in the Brotli decoder included in Node.js. Brotli is a compression algorithm developed by Google, primarily used to compress web transmission data or to decompress transmitted compressed data. When a web application receives data compressed with Brotli, the Brotli decoder decompresses it. However, if a threat actor sends maliciously crafted compressed data, the vulnerable Brotli decoder fails to recognize it as an error and attempts to continue processing the data, thereby exposing the vulnerability. A threat actor could exploit this vulnerability to terminate the Node.js process, expose memory information, or even trigger remote code execution.
Given that this vulnerability can lead not only to service disruption but also to memory information exposure and remote code execution, the Node.js project has rated its severity as “High.” Additionally, the CVE record for the Brotli library registered by Google lists a CVSS v4.0 score of 9.2, and the Imperva Red Team has named this vulnerability “Node2Shell.” In this article, we analyze Brotli’s block transition mechanism and the decoder’s error-handling process, and examine the paths through which a vulnerable decoder is invoked in Node.js applications, along with mitigation strategies.
Technical Background
Brotli Compression Technology
When exchanging data over the web, the original content is often compressed to reduce the amount of data transmitted. Brotli is one of the compression methods available for this purpose; the receiving end must decompress the Brotli-compressed data back to its original form before it can be used. The Brotli decoder is responsible for this decompression process.
The decoder restores the original content while reading the compressed data, processing it sequentially in units called blocks. Since the compressed data contains instructions regarding the portion to be processed in the current block and the content to be decompressed next, the decoder moves on to the next block and continues processing even after completing the current block, provided there is still content left to decompress.
CVE-2026-111497
Causes of Vulnerability
The problem begins when a threat actor feeds the decoder compressed data that has been manipulated to be inconsistent. According to the instructions in the compressed data, there is still content to be decoded, but the portion that can be decoded from the block the decoder is currently processing has already been completed. Consequently, the decoder attempts to move on to the next block to decode the remaining content.

However, when it actually tries to move on, there is no information for the block to switch to. Simply put, it indicates that more data needs to be decoded, but there is no block available to process next. Since the compressed data is inconsistent, the decoder should detect an error here and stop; this is not a situation that can be resolved by receiving more data.
However, a vulnerable decoder may, in some cases, misinterpret this error as meaning, “The problem will be resolved once more compressed data arrives.” It stores the newly received data in its small internal storage and attempts the same operation again; however, since the problem wasn’t caused by insufficient data in the first place, the inability to switch blocks remains unchanged no matter how much more data is received. If this process repeats, data may eventually be written beyond the bounds of the internal storage—a phenomenon known as out-of-bounds writing.
In another scenario, there was an issue where the decoding process continued without verifying that the block transition had failed. However, the internal storage overflow described earlier corresponds to a case where the error was mistaken for a lack of data. The patched decoder distinguishes between this “unconvertible” state and a genuine lack of data, immediately halting the process of decompression if the compressed data is found to be invalid.
Potential Impacts of the Vulnerability
An out-of-bounds write vulnerability occurs when a program writes data to a memory area outside its designated storage space. If the memory of a Node.js process is compromised in this way, it can cause service disruption or expose memory information; under certain conditions, it can also lead to remote code execution, allowing a threat actor to execute code on the server.
Of course, sending manipulated compressed data does not immediately result in remote code execution in every environment. In the publicly disclosed reproduction, code execution was confirmed only with specific Node.js builds and application configurations, while the patched version rejected the same input.
Attack Flow Analysis
So, what is the sequence of events in an actual attack? The threat actor first identifies a service running a vulnerable version of Node.js. However, simply having a vulnerable version does not guarantee a successful attack. The service must actually have a process for decompressing Brotli-compressed data received from external sources, and the threat actor must be able to deliver the manipulated data to that decompression process.
Depending on the service’s functionality, there are three main points where a threat actor can inject manipulated Brotli data:
- When included in the body of an HTTP POST request sent by a client
- When it is included in a response received by the Node.js application from an external server
- When a Node.js application directly processes Brotli data or files
The most common entry point is an HTTP request sent by a client to the server. If the request body is compressed using Brotli, an application that supports this format will decompress it before using the contents. Therefore, if a threat actor includes tampered compressed data in the request body, that data can be passed to the Brotli decoder.
Manipulated Brotli data can also be introduced while a Node.js application is processing a response received from an external server. If a threat actor controls the external server’s response or tricks the application into fetching data from an address specified by the threat actor, the response can contain manipulated data.
The tampered data does not necessarily have to be transmitted directly via a web request. The same issue can occur if the application directly decompresses compressed files or messages received from other systems. Files can be uploaded through web requests, and messages can be delivered through separate systems or message queues. Regardless of the delivery path, once the application actually decompresses the data, it reaches the vulnerable Brotli decoder.
When the vulnerable decoder processes the tampered compressed data, it exhibits incorrect behavior by attempting to switch to a nonexistent next block. Rather than recognizing this as a format error and terminating the operation, the decoder incorrectly interprets the situation as requiring additional input. As a result, more data is written than the allocated storage space can hold, causing memory corruption in the Node.js process. The Figure below illustrates the entire flow, from the moment the threat actor sends the manipulated Brotli data to memory corruption and remote code execution.

Memory corruption can cause service disruption or lead to the exposure of information stored in memory. Furthermore, if certain conditions—such as the memory structure and execution environment—are met, it can lead to remote code execution, where the threat actor’s intended code is executed on the server. The two videos below show the results of successfully replicating DoS and RCE attacks in a vulnerable Node.js environment. Since the conditions required for a successful attack vary by execution environment, actual attack outcomes may also differ depending on the situation.
[Video 1] DoS demonstration using Node2Shell
[Video 2] RCE Demonstration Using Node2Shell
Mitigation Measures
Apply a Patch with the Fixed Version
The most reliable countermeasure is to update the Node.js currently in use on the Service to a version that has been patched to address the vulnerability or later. The first patched versions for each branch, released by the Node.js project on October 21, 2026, are as follows.
|
Node.js Series |
Vulnerable Version |
Fixed Version |
|---|---|---|
|
22.x |
Less than 22.23.4 |
22.23.4 or later |
|
24.x |
Less than 24.22.1 |
24.22.1 or higher |
|
26.x |
Less than 26.12.1 |
26.12.1 or higher |
[Table 1] Revision versions by branch released by the Node.js project
When updating, you should not simply check the Node.js version installed on the server. Since the executable file actually used by the Service may be included separately in a container image or deployment package, you must perform file replacement and then restart the relevant processes. Afterward, verify that the updated version has been applied to the running Service, and if any products other than Node.js use the Brotli library separately, you must also check whether patches have been applied to those products.
If the Patch Version Cannot Be Applied
It may be difficult to update to the patched version immediately if you need to update multiple servers sequentially or must first verify that the Service is functioning properly. There may also be cases where a product includes Node.js, requiring you to wait for an update from the vendor. In such cases, first identify the Path through which external Brotli data enters the Service and is decompressed, and temporarily restrict access to that Path until the update is complete.
For example, if there is a feature that processes Brotli-compressed data among web requests, you can restrict those requests until the update is complete. Another method is to block Brotli-compressed requests using a proxy or web application firewall. For features that retrieve Brotli-compressed responses from external servers, you can restrict them to accept responses only from authorized servers or, if necessary, temporarily suspend those features.
Such restrictions are temporary measures intended to reduce the risk of attack, but they may also affect normal web requests or external integration features. Therefore, it is advisable to verify whether the feature is essential to the Service before applying such restrictions and to maintain them only until the update is complete.
Conclusion
Node2Shell demonstrates that memory issues within the runtime can be exploited for attacks even during routine compression data processing. Even if an application does not directly use the Brotli functionality to decompress data, the Brotli decoder may be invoked while processing the body of a web request or a response received from an external server. Therefore, simply checking the Node.js version installed on the server or publicly exposed addresses may cause you to overlook actual attack paths, so additional caution is required.
To address this, verify the executable file and version actually used by the currently running Node.js process, and prioritize updating to a version where the vulnerability has been fixed. In addition, you must verify how Brotli-compressed data—including data received through web request bodies, responses from external servers, files, and message queues—that could be manipulated by a threat actor is processed within the Service. In environments where immediate updates are difficult, it is important to restrict unnecessary Brotli functions for decompression and, after updating, verify that abnormally manipulated compressed data is rejected by the actual Service.
This incident demonstrates that not only features directly implemented in the application but also the processing performed internally by frameworks or runtimes can be exposed to attacks. Therefore, when addressing similar vulnerabilities, it is necessary to identify not only the versions of the components in use but also which service functions call those components.
Source
- https://nodejs.org/en/blog/vulnerability/october-2026-security-releases
- https://nodejs.org/en/blog/release/v22.23.4
- https://nodejs.org/en/blog/release/v24.22.1
- https://nodejs.org/en/blog/release/v26.12.1
- https://github.com/CVEProject/cvelistV5/blob/main/cves/2026/111xxx/CVE-2026-111497.json
- https://github.com/google/brotli/commit/0ed4268a4401abcb44720963
- https://github.com/nodejs/node/commit/49dff6f57a
- https://www.rfc-editor.org/rfc/rfc7932
- https://expressjs.com/en/guide/migrating-5/
- https://expressjs.com/en/resources/middleware/body-parser/
- https://www.imperva.com/blog/node2shell-from-brotli-data-to-remote-code-execution/