
Node.js has vulnerabilities too. On October 21, 2026, the Node.js project published a security release that fixes 10 vulnerabilities: 4 rated High, 3 Medium and 3 Low (Node.js official blog). The fixed versions are 22.23.4, 24.22.1 and 26.12.1. This is a separate matter from the PHP “PHP2Shell” vulnerabilities.
This article is written for engineers who run Node.js. It is built around primary sources, such as the Node.js official blog, the release notes (24.22.1, 22.23.4) and the CVE record, and it separates what is confirmed from what is not. Sources are cited next to each statement. The information is current as of October 22, 2026.
Status of each release line, based on the official release schedule (the schedule.json file in nodejs/Release).
| Line | Status (as of Oct 22, 2026) | Fixed version in this release | Planned EOL |
|---|---|---|---|
| 18.x | EOL | None | Apr 30, 2025 |
| 20.x | EOL | None | Apr 30, 2026 |
| 22.x | Maintenance LTS (since Oct 21, 2025) | 22.23.4 | Apr 30, 2027 |
| 24.x | Maintenance LTS (since Oct 20, 2026) | 24.22.1 | Apr 30, 2028 |
| 25.x | EOL | None | Jun 1, 2026 |
| 26.x | Current (moves to LTS on Oct 28) | 26.12.1 | Apr 30, 2029 |
24.x moved from Active LTS to Maintenance LTS on October 20. Maintenance is the phase in which only critical bug fixes and security fixes land. 26.x is scheduled to become LTS on October 28.
The Node.js official blog does not describe the cause or attack conditions of each issue in detail. It gives the title, the affected lines, the reporter and the fixer. The “What the fix does” column in the table below comes from the titles of the fix commits listed in the 24.22.1 and 22.23.4 release notes.
| CVE | Severity | Title (paraphrased) | Affected lines | What the fix does |
|---|---|---|---|---|
| CVE-2026-111497 | High | Out-of-bounds write in the Brotli decoder allows remote code execution | 26.x, 24.x, 22.x | Cherry-picks the Brotli fix |
| CVE-2026-105482 | High | dns.resolve truncates names containing NUL characters |
26.x, 24.x, 22.x | Validates dns.resolve input for NUL bytes |
| CVE-2026-105483 | High | TLS certificate hostname verification can be bypassed when an IP address is written with full-width digits | 26.x, 24.x | Fixes a regression in IP normalization |
| CVE-2026-106069 | High | TLS hostname verification can be bypassed when a hostname is loosely parsed as an IP address | 26.x, 24.x, 22.x | Rejects non-canonical IP addresses in TLS |
| CVE-2026-105481 | Medium | A keep-alive socket processes a response written before the request was sent | 26.x, 24.x, 22.x | Makes the HTTP agent’s data protection work without I/O |
| CVE-2026-106072 | Medium | With a non-canonical IPv4 hostname, a certificate’s DNS SAN can be used to authenticate an IP endpoint | 26.x, 24.x, 22.x | Rejects non-canonical IP addresses in TLS (same fix as 106069) |
| CVE-2026-106074 | Medium | The random-value caches behind crypto.randomUUID() and randomInt() are saved into snapshots and SEAs, so every process repeats the same values |
26.x, 24.x, 22.x | Resets the random cache across snapshots |
| CVE-2026-106070 | Low | After ZIP header validation fails, ZipFile returns attacker-controlled bytes |
26.x only | Not confirmed (I have not retrieved the 26.x release notes) |
| CVE-2026-106071 | Low | A wildcard lookup in the Permission Model grants excessive file system permissions | 26.x only | Not confirmed (I have not retrieved the 26.x release notes) |
| CVE-2026-106073 | Low | fs.realpathSync can bypass the Permission Model |
26.x, 24.x, 22.x | Checks the Permission Model in realpathSync |
Node.js has not published CVSS scores for these CVEs (official blog). Of the four CVE records I tried to check as of October 22 (CVE-2026-111497, 105482, 105483 and 106069), I could retrieve only CVE-2026-111497 on cve.org.
The title on the Node.js official blog is “an out-of-bounds write in the Brotli decoder allows remote code execution.” According to the CVE record, the cause is not Node.js itself but Google’s google/brotli library.
The Node.js fix pulls in this Brotli fix (24.22.1 release notes). The reporter is listed as OpenAI Codex Security (official blog).
As for what is affected, the Vercel bulletin explains it this way: a Node.js process is affected when it decompresses attacker-controlled Brotli data, either as a request body or as a fetched response. Node.js does not decompress Brotli data on its own initiative. The official blog does not say which specific APIs are involved.
My own view: places worth checking include Brotli decompression in zlib (such as zlib.brotliDecompress), middleware that decompresses requests sent with Content-Encoding: br, and any code that decompresses Brotli-compressed responses fetched from external APIs.
Vercel states that researchers demonstrated process memory disclosure and command execution against unpatched versions (Vercel bulletin). It does not mention any exploitation in the wild.
Brotli is embedded in far more than Node.js. Because the flaw is in the library itself, other products that use Brotli, such as browsers, HTTP clients, web server modules and language bindings, each need their own update check. As of October 22, google/brotli’s GitHub security advisories page had no published advisories.
CVE-2026-105483, CVE-2026-106069 and CVE-2026-106072 are all cases where TLS certificate hostname verification does not behave as expected around “non-canonical” IP address notations, such as full-width digits or strings that are loosely parsed as IP addresses. The fixed versions now reject non-canonical IP addresses in TLS (release notes).
My own view: if your configuration or environment variables write destination IP addresses in an unusual notation, connections may be refused after the update. Always test outbound connections after updating.
dns.resolve truncates names that contain NUL characters and resolves the shortened name. The fix validates input for NUL bytes (release notes)randomUUID() and randomInt() are stored in user snapshots and in SEAs (single executable applications). As a result, every process started from the same snapshot repeats the same values--permission). If you use the Permission Model, check themThe release also updates dependencies. According to the 24.22.1 release notes:
| Dependency | 24.22.1 |
|---|---|
| OpenSSL | 3.5.9 |
| undici | 7.30.1 |
| c-ares | 1.34.9 |
| Root certificates (NSS) | 3.131.1 |
| tzdata (time zones) | 2026e |
In 22.23.4, undici is 6.29.1 and SQLite is 3.53.4, and the rest are the same. The official blog lists “ca-cert (eMudhra Intermediate CA Compromise)” under dependency updates. The root certificate store was updated in response to an issue involving an eMudhra intermediate certificate authority. The Node.js blog does not give details on this, though. For details, check announcements from the certificate authority and the browser vendors.
First, check which version you actually run in production, in CI and in containers.
node -v
An example with nvm:
nvm install 24.22.1 # 22.23.4 for the 22 line, 26.12.1 for the 26 line
nvm use 24.22.1
For Docker, pull the base image again, rebuild without the cache and check the version inside the container.
docker build --pull --no-cache -t myapp .
docker run --rm myapp node -v
Rebuilding the container is also described in an explainer on ToolScope (a secondary source, in Japanese). I could not confirm when the official Docker images (nodejs/docker-node) were published, so pull again and verify with node -v. If you pin the version in .nvmrc, the engines field of package.json, setup-node in CI and so on, update those too.
If you use snapshots or SEAs, rebuild them with a fixed runtime. The official blog does not mention rebuilding. Still, a random cache that was already saved would likely remain unless you rebuild (my own view).
According to the Vercel bulletin, on October 21 Vercel rolled out a WAF rule for this vulnerability to all projects and applied it automatically. It does not cover traffic that does not pass through Vercel’s network, or responses a function fetches from an external server. Vercel is moving its managed runtimes to the fixed versions. What you need to do on your side:
Separately from the Node.js update, Next.js published an out-of-band security update on October 14. The fixed versions are 16.4.1 (Active LTS) and 15.5.28 (Maintenance LTS). It fixes 2 Critical issues and 1 High issue.
use cache returns a typed array (Critical, GHSA-673q-mjm6-r5xr). There is no workaround, so you need to updatesharp to 0.35.5 or laterIf you use Next.js, check both the Node.js update and the Next.js update.
| Item | What is known | Reliability |
|---|---|---|
| Official blog | Nothing stated about exploitation. No workaround stated either | Primary source |
| Demonstration | Vercel says researchers demonstrated memory disclosure and command execution on unpatched versions | Vendor statement |
| Attacks in the wild | As of October 22, I found no reports of attacks in the wild, within what I was able to check | Not confirmed |
| Severity | High per Node.js (official blog). The Brotli CVE record gives CVSS v4.0 9.2 (CRITICAL) | Ratings differ |
| Details of each CVE | The official blog is mostly titles. Of the four I checked, three CVE records were not yet published when I looked | Details are limited |
The absence of attack reports is not proof of safety. Brotli is used well beyond Node.js, so a wide check is needed.
The Node.js release plan is changing too. According to the official announcement “Evolving the Node.js Release Schedule,” starting with Node.js 27 there will be one major release a year, in April, promoted to LTS in October. The odd and even distinction goes away, and every release becomes LTS. The LTS period is 30 months. The project gives the maintenance burden as one reason, saying it had become hard to maintain security releases across four or five lines.
In schedule.json, 27.x Alpha starts October 28, and 27.0.0 is planned for April 22, 2027. 26.x is the last release under the old model.
The practical decisions that follow from this incident:
Today
This week
This quarter
We are currently taking free consultations on security. Questions like "Is our site safe?" or "Where should we start checking?" are welcome.
