Under attack? Get incident response help

info@angelforce.eu
Vulnerabilities

Node.js October 2026 security release: Brotli RCE and TLS bypasses

Node.js 22.23.4, 24.22.1 and 26.12.1 fix ten flaws, including a Brotli decoder bug that allows code execution. Who is exposed, and how to update and verify.

Also in:TürkçeDeutschFrançaisEspañolItalianoPolskiNederlandsEesti

Illustration: Node.js October 2026 security release: Brotli RCE and TLS bypasses

On 21 October 2026 the Node.js project released 22.23.4, 24.22.1 and 26.12.1. They fix ten vulnerabilities, four of them rated high. The most serious one, CVE-2026-111497, is an out-of-bounds write in Node's Brotli decoder: malformed compressed data can corrupt memory, and the hosting company Vercel reports that researchers used it to read process memory and run commands with the rights of the Node.js process. Two other high-severity flaws let a TLS certificate pass the hostname check when it should not. Node.js 20 and 25 have reached end of life and get no fix.

Which versions are fixed

Release lineFixed inStatus
26.x26.12.1current
24.x (LTS)24.22.1supported
22.x (LTS)22.23.4supported
25.xno fixend of life, move to 26 or 24
20.xno fixend of life since 30 April 2026, move to 22 or 24

What the ten flaws are

CVESeverityProblemLines
CVE-2026-111497HighBrotli decoder out-of-bounds write, can lead to code execution26, 24, 22
CVE-2026-105483HighTLS hostname check passes when the IP is written with full-width digits26, 24
CVE-2026-106069HighTLS hostname check passes when the host loosely resolves to an IP address26, 24, 22
CVE-2026-105482Highdns.resolve cuts names at a NUL character26, 24, 22
CVE-2026-105481MediumA keep-alive socket can accept a response written before the request was sent26, 24, 22
CVE-2026-106072MediumA DNS name in a certificate can authenticate an IP endpoint for non-canonical IPv4 hosts26, 24, 22
CVE-2026-106074MediumrandomUUID() and randomInt() repeat the same values in startup snapshots and single executable apps26, 24, 22
CVE-2026-106073LowPermission Model bypass with fs.realpathSync26, 24, 22
CVE-2026-106070LowZipFile returns attacker-controlled bytes after a failed header check26
CVE-2026-106071LowPermission Model grants too much file access through wildcards26

The releases also update bundled components: c-ares, Undici, the trusted CA list (removing the compromised eMudhra intermediate CA), OpenSSL on 24 and 22, and SQLite on 22.

Who is exposed to the Brotli flaw

Node.js does not decode Brotli on its own. You are exposed when your code, or a library it uses, decompresses Brotli data that someone else controls. That happens more often than it sounds:

  • The built-in fetch() decodes responses with Content-Encoding: br automatically. A service that fetches URLs chosen by users, webhooks or third-party APIs can receive a malicious response.
  • axios, got and node-fetch decode compressed responses by default too.
  • Express 5 (body-parser 2) decodes Brotli request bodies by default, so an API can receive the data directly from an attacker.
  • Any call to zlib.brotliDecompress, zlib.createBrotliDecompress or DecompressionStream on uploads or third-party data.

Patch first where these meet the internet: public APIs that accept compressed bodies, services that fetch user-supplied URLs, and anything that unpacks uploaded files.

The TLS flaws mainly matter when an attacker can obtain a certificate from a CA your client trusts that contains an IP-shaped DNS name, and the DNS flaw when your code passes outside input to dns.resolve. According to the fix commit, the TLS issues are not easy to exploit, but the same update closes them.

Step 1: find every Node.js runtime

On Linux, list every node binary with its version:

sudo find / -xdev -type f -name node -perm -u+x 2>/dev/null | while read -r n; do echo "$n: $("$n" --version 2>/dev/null)"; done

Check which runtime the running processes use:

for p in $(pgrep -x node); do echo "$p $(sudo readlink -f /proc/$p/exe)"; done

In Docker, check every running container:

for c in $(docker ps --format '{{.Names}}'); do echo "$c: $(docker exec "$c" node --version 2>/dev/null)"; done

Also check version managers (nvm, fnm, Volta, asdf), CI runners, build images, Electron apps and serverless functions, where the runtime version is set in the project configuration.

Step 2: update

Ubuntu and Debian with the NodeSource packages:

sudo apt update && sudo apt install --only-upgrade nodejs && node --version

With nvm:

nvm install 24.22.1 && nvm alias default 24.22.1

Containers: change the base image to a fixed version, for example node:24.22.1-alpine or node:22.23.4-bookworm-slim, rebuild and redeploy. Updating the host does not change what runs inside a container.

Serverless and hosting platforms: on Vercel, projects on 22.x and 24.x are patched by Vercel, and Vercel added firewall rules against the inbound attack; projects still on 20.x must switch to 22.x or 24.x and redeploy. On other platforms, check the provider's notice and redeploy when the patched runtime is available.

Distribution packages such as Ubuntu's own nodejs package often lag behind. If node --version does not show 22.23.4, 24.22.1 or 26.12.1 (or a distribution build that names these CVEs), use the official releases.

Step 3: restart and verify

A running process keeps the old runtime until it restarts. After a package update on Linux, this lists node processes that still run the replaced binary:

sudo ls -l /proc/*/exe 2>/dev/null | grep -i 'node.*(deleted)'

Restart those services (for example with systemctl restart, pm2 reload all or a new deployment) and run the commands from step 1 again.

If you cannot update today

None of these replaces the update, but they lower the risk for a few days:

  • Reject Brotli request bodies before they reach the app, for example in NGINX with if ($http_content_encoding ~* br) { return 415; }, or in a middleware that runs before the body parsers.
  • Turn off automatic decompression for requests to untrusted servers: decompress: false in axios and got, compress: false in node-fetch, or undici's request(), which does not decompress. The built-in fetch() cannot be switched off.
  • Run fetches of user-supplied URLs in a separate process with as few rights as possible.
  • Before passing outside input to dns.resolve, reject names that contain a NUL character.

If you are not sure which of your services decode untrusted data, or you need help updating a production system without downtime, our secure software and managed security teams can help.

How we can help

Secure software

We build security into software from the first commit, and we build security tools of our own.

Contact us
AngelForce team

Written by the AngelForce team: security consultants with CEH, LPT Master and CISA certifications who test, monitor and defend systems for organisations across Europe.

Written with AI assistance from public sources listed below, and reviewed by the AngelForce team before publication.

Sources

  1. nodejs.org/en/blog/vulnerability/october-2026-security-releases
  2. vercel.com/kb/bulletin/node-js-security-advisory
  3. atlasum.net/blog/cve-2026-111497-nodejs-brotli-decoder
  4. lilting.ch/en/articles/nodejs-tls-dns-brotli-security-release
  5. wardio.net/guides/nodejs-brotli-cve-2026-111497/

Articles about Vulnerabilities

Tell us what you need to protect

Describe your environment and what you want to achieve. We will reply by email.

Contact us
info@angelforce.eu

AngelForce OÜ · Tallinn, Estonia