Node ships three security releases in one day: 11 CVEs, five high, two in tls and one in dns

On October 21 Node released 26.12.1, 24.22.1 and 22.23.4 together, fixing 11 CVEs. The high-severity ones cluster in tls and dns input parsing, alongside two permission-model edge cases and a root store bump to NSS 3.131.1.

On October 21 Node shipped three versions at once: 26.12.1 (Current), 24.22.1 (Krypton LTS) and 22.23.4 (Jod LTS). All three are security releases fixing the same 11 CVEs. The conclusion is short: if you run Node on a server, change the version today. This is not a patch that waits for the next sprint.

What was fixed

Grouped by component rather than by version:

Component Issue Severity
tls reject non-canonical IP addresses (CVE-2026-106069, CVE-2026-106072) High
tls fix an IP normalization regression (CVE-2026-105483) High
dns validate resolve inputs for null bytes (CVE-2026-105482) High
src / brotli expose BROTLI_DECODER_ERROR_FORMAT_BLOCK_SWITCH, cherry-pick upstream fix (CVE-2026-111497) High
http agent data guard fails without I/O (CVE-2026-105481) Medium
crypto reset random caches across snapshots (CVE-2026-106074) Medium
zlib stop caching invalid ZIP local headers (CVE-2026-106070) Low
src fix the fs permission tree node on wildcard nodes (CVE-2026-106071) Low
permission check the permission model in realpathSync (CVE-2026-106073) Low

Two more items are not CVEs but matter: a V8 backport (93cd21e8254b) and a root certificate update to NSS 3.131.1.

The v26.12.1 release page opens by stating it is a security release

Four of the five high-severity bugs are input parsing

Three tls entries plus one dns entry are the same class of bug: treating an externally supplied string as something structural without validating it hard enough.

  • “Reject non-canonical IP addresses” — ::ffff:127.0.0.1, 127.0.0.1, IPv4 with leading zeros, IPv6 hex in different cases: all the same address semantically. If one code path decides “is this internal?” by string comparison and another connects using the normalized form, the two disagree — and that disagreement is the bypass.
  • “Validate dns resolve inputs for null bytes” — put \0 in a string and the C layer truncates while JS still sees the whole thing. Seeing this in 2026 tells you boundary validation is still the easiest place to miss.
  • “Fix an IP normalization regression” is the most instructive: it repairs a regression introduced by an earlier fix. Security patches breaking things is not rare, which is exactly why a security release is often followed by a patch release.

Scrolling down, the CVEs are listed one by one with their authors

What the two permission-model fixes tell you

Both permission entries are low severity, but the direction is interesting: one is about fs permission tree nodes on wildcard nodes, the other makes realpathSync go through the permission model.

--permission exists so that even injected code can only touch allowed paths. It builds a tree of path prefixes and checks against it. Two classic bypasses follow:

  1. Wildcard nodes (for example --allow-fs-read=/data/*) are a special node in that tree, and the check can take the wrong branch;
  2. realpathSync resolves symlinks — if it skips the permission check, then “check first, resolve later” is bypassable with a symlink.
# typical use: allow reading exactly one directory
node --permission --allow-fs-read=/srv/app/config app.js

With these two fixed, the model finally closes the “path normalization plus symlinks” chain. I still would not treat --permission as a sandbox. It is one layer of defence in depth, not an isolation boundary.

What I did about it

This site has no Node server, but the build runs on CI, and whatever line node-version points at should follow. Build machines execute dependency code too, and they parse URLs and DNS names too. The change is one line:

- uses: actions/setup-node@v4
  with:
    node-version: 24.22.1   # or track the current 26.x

Note the root certificate item as well: NSS 3.131.1 means new roots came in and some may have gone out. If a certificate chain depends on a removed root, handshakes start failing after the upgrade — and that never reproduces locally, only on some outbound request in production.

Node’s release schedule page — Current and the two LTS lines at a glance

One-line verdict

How many of the 11 CVEs are remotely reachable depends on your code paths — but if you serve HTTPS, the three tls entries concern you. There is no “let me evaluate first” for a security release: upgrading costs one build, not upgrading costs an incident with unknown probability.

Node’s blog list, three security announcements on the same day

← Back to all posts

Comments

…