Node.js: critical Brotli vulnerability (CVE-2026-111497) and nine more fixes from 21 October
A flaw in Brotli decompression allows code execution in Node.js applications that process data from outside sources. Affected versions, which applications are exposed, how to update, and what else the 21 October 2026 release fixes.
On 21 October 2026 the Node.js team released fixes for 10 vulnerabilities across all supported versions. The most serious, CVE-2026-111497, is in Brotli decompression and can allow code execution on the server. Node.js applications that decompress Brotli data from an outside source are affected: responses from other servers or compressed requests from visitors. Some coverage calls the vulnerability Node2Shell.
In short
- CVE-2026-111497: an out-of-bounds write in the Brotli decoder.
- Node.js rates it High; Google, which maintains the Brotli library, scores it 9.2 out of 10 on CVSS 4.0.
- Fixed versions: 26.12.1, 24.22.1 and 22.23.4.
- Node.js 20, 23 and 25 are no longer supported and receive no fix.
- As of 23 October there are no confirmed attacks in the wild, but researchers have already demonstrated code execution in a test environment.
Which applications are affected
The flaw is in Google's Brotli library, which Node.js bundles and uses in its zlib module. It is dangerous when an application decompresses Brotli data that an attacker can control. That happens in two ways.
Responses from other servers
The built-in fetch() automatically decompresses responses with Content-Encoding: br. So do the axios, got and node-fetch libraries by default. Applications that load URLs supplied by users or third parties are exposed:
- link previews in chats, CRMs and help desks;
- automations and integrations that call external APIs and webhooks;
- image optimisation from external URLs, for example in Next.js;
- tools that collect data from websites.
A firewall in front of the application does not see these responses, because the application itself opens the outbound connection.
Compressed requests from visitors
Express 5 uses body-parser 2.x, which decompresses request bodies by default, Brotli included. Any request with Content-Encoding: br to an Express 5 API therefore reaches the vulnerable code. Express 4 (body-parser 1.x) does not support Brotli and is not exposed this way. A server written only with the Node.js http module does not decompress requests by itself.
Other software
The flaw also affects any other software that uses Brotli versions 1.0.3 to 1.2.0. Google has released fixed versions 1.0.10, 1.1.1 and 1.2.1. In some distributions, such as Debian, Node.js uses the system libbrotli library instead of the bundled one. There the fix arrives with the system package update, once the distribution publishes it.
| Node.js version | Status |
|---|---|
| 26.x | fixed in 26.12.1 |
| 24.x (LTS) | fixed in 24.22.1 |
| 22.x (LTS) | fixed in 22.23.4 |
| 20.x and older, 23.x, 25.x | no fix; move to a supported version |
How the vulnerability works
Brotli is a compression format websites use to send less data. When decompressing, the decoder writes the output into a memory buffer. A specially crafted Brotli stream makes the decoder write past the end of that buffer and corrupt neighbouring memory. According to Google, this can lead to memory disclosure, a crashed process or code execution.
The Node.js fix adds a check that rejects the invalid stream earlier, with a new error code, BROTLI_DECODER_ERROR_FORMAT_BLOCK_SWITCH.
How serious the threat is
- Google scores the vulnerability 9.2 on CVSS 4.0, noting that the attack depends on conditions in the specific environment. Node.js classifies it as High.
- Imperva reports achieving code execution in test applications on the official Node.js 24.22.0 image after several attempts, while version 24.22.1 rejects the same input.
- A published exploit achieved code execution only on a deliberately weakened build. On a standard build the result was a crashed process and a limited memory leak.
- CISA had not added the vulnerability to its catalogue of actively exploited vulnerabilities as of 23 October.
With PHP2Shell the same week, the first attack attempts were recorded before the fixes were even released. Update without waiting for confirmed attacks.
The other fixes
The release fixes nine more vulnerabilities. Most affect applications that open connections to other servers themselves.
- CVE-2026-106069 and CVE-2026-105483 (High): with a non-standard IP address notation, such as
127.1or Unicode fullwidth digits, Node.js can accept a TLS certificate that was not issued for that address. Combined with a man-in-the-middle attack, this lets an attacker impersonate the server the application connects to. - CVE-2026-106072 (Medium): a related issue in which a certificate for a domain name authenticates a connection to an IP address written in a non-standard form.
- CVE-2026-105482 (High):
dns.resolvetruncates names at a NUL character. An application that checks a user-supplied address and then resolves it may resolve a different name from the one it checked. - CVE-2026-106074 (Medium): in applications built as a single executable application (SEA) or with a startup snapshot,
crypto.randomUUID()andcrypto.randomInt()return the same values in every process. Such applications must be rebuilt with the fixed version, not just updated. - CVE-2026-105481 (Medium): a keep-alive connection can accept a response sent before the request itself.
- Three low-severity issues affect the experimental Permission Model and the ZIP module in version 26.
- The trusted certificate list now blocks eMudhra intermediate certificates after their compromise.
What to do now
1. Find the versions you run
node -v on the server shows only one installation. Also check:
- Docker images: the version comes from the base image, such as
node:22, and only changes when the image is rebuilt; - continuous integration (CI) servers and developer machines;
- applications distributed as a single executable and Electron desktop applications.
npm audit checks only the packages in the project, not Node.js itself, and will not report this vulnerability.
2. Update
- Servers with NodeSource packages:
apt update && apt install nodejs, then check withnode -v. - nvm and similar tools: install the new version of the same line, for example
nvm install 22, and make it the default. - Docker: rebuild images with
docker build --pulland redeploy them. - Distributions that use the system
libbrotli(Debian and derivatives): also update thelibbrotli1package once the distribution publishes a fix. Check withldd $(command -v node) | grep brotli; if it prints nothing, Node.js uses its bundled library. - Node.js 20 or older: move to 22 or 24. This usually requires checking your dependencies.
3. Restart every process
Running processes keep using the old version until they are restarted. This applies to systemd services, pm2 processes and anything started by hand or from cron.
4. Temporary measures
- If an Express 5 API does not need to accept compressed requests, set
inflate: falseon body-parser. Also update body-parser to 2.4.0 or 1.20.9 for the separate vulnerability CVE-2026-111181, in which a single compressed request with trailing bytes crashes the process. - When the application loads URLs you do not control, turn off automatic decompression:
decompress: falsein axios and got,compress: falsein node-fetch. - Do not disable TLS certificate verification (
rejectUnauthorized: falseorNODE_TLS_REJECT_UNAUTHORIZED=0) to get around errors after updating. That removes the protection the TLS fixes restore.
How to check for signs of an attack
No indicators of compromise have been published so far. Unexpected Node.js process exits and decompression errors in the logs after 21 October do not prove an attack, but they are a reason to look closer. If in doubt, check for new files and cron jobs belonging to the user the application runs as, and for outgoing connections to unknown addresses. Change the passwords and API keys the process has access to, for example in .env files.
If the attacker had access to personal data, this is a personal data breach that in most cases has to be reported to the data protection authority within 72 hours. Companies within the scope of the Bulgarian Cybersecurity Act also send an early warning within 24 hours.