Site icon NexGismo

Node.js Security Release: 16 HTTP/2 and TLS Fixes to Patch

Node.js Security Release: 16 HTTP/2 and TLS Fixes to Patch
TL;DR
  • What happened: Node.js shipped fixes for 16 CVEs on November 11, 2026: 7 High, 6 Medium, 3 Low.
  • Who is affected: HTTP/2, HTTPS and TLS servers on 22.x, 24.x and 26.x below the fixed versions.
  • What to do now: Upgrade to 22.23.5, 24.22.3 or 26.13.1, then restart every process.
  • Interview angle: Use-after-free in a “memory-safe” runtime, HTTP/2 resource accounting, and SNI-based mTLS.

The Node.js security release of November 11, 2026 patches 16 vulnerabilities across the 22.x, 24.x and 26.x lines. The worst let an unauthenticated client crash a server or read heap memory through HTTP/2 and HTTPS. Upgrade to 22.23.5, 24.22.3 or 26.13.1 and restart every Node.js process. No workaround is listed.

Use-after-free is a memory bug where code keeps using a buffer or object after it has been released. The freed memory may now hold someone else’s data. JavaScript itself is garbage-collected, but Node.js runs C++ parsers and protocol libraries underneath, and that is where these bugs live.

This Node.js security release matters because it targets the network layer every web server depends on. Seven of the 16 issues are rated High in the official advisory. Five were credited to Chris Rohlf working with Claude and Anthropic Research. Below you get the affected versions, a feature-to-CVE triage table, a patch checker we ran, and the interview concepts behind the bugs.

What changed in the Node.js security release, and who is affected?

The release went out on Wednesday, November 11, 2026, according to the Node.js advisory. As of that day, Cyber Kendra noted that Node.js had published no CVSS scores, so severity below is the project’s own High/Medium/Low rating.

Node.js November 2026 security release — fixed versions (source: Node.js advisory)
Release line Fixed version Highest severity Bundled deps updated
26.x 26.13.1 High llhttp, undici
24.x 24.22.3 High llhttp, undici, sqlite
22.x 22.23.5 High llhttp, sqlite

Which CVEs hit which features?

The advisory lists CVEs by number. Teams triage by feature. So we regrouped the advisory’s 16 entries by the API surface that exposes them.

Feature-to-CVE triage table built from the Node.js advisory
If your app uses… Relevant CVEs Worst impact listed
Any node:http2 server CVE-2026-123863, -123865, -123866, -123868 Unauthenticated crash; heap memory sent to peer
respondWithFile() / respondWithFD() CVE-2026-123874, -123875 Use-after-free; NULL dereference crash
session.altsvc() CVE-2026-123828 One-byte heap overflow
HTTPS with res.flushHeaders() before body end CVE-2026-123864 Read other connections’ memory, including TLS keys
TLS callbacks: SNICallback, OCSP, session resume CVE-2026-126051 Unauthenticated process crash
Per-host mTLS via server.addContext() CVE-2026-123867, -123872 Client-cert policy bypass
https.Agent with custom ca CVE-2026-123877 TLS session reused under the wrong trust store
Proxy config with credentials CVE-2026-123871 Credentials leaked into error logs
Permission Model flags CVE-2026-123829, -106071 Path names revealed; wildcard over-match
zlib deflate.params() while streaming CVE-2026-123862 Uncatchable internal assertion

How does it work?

Most of the High bugs share one theme: object lifetimes in C++ code that drives sockets. A stream, buffer or session gets torn down while another path still holds a pointer to it.

  1. A client opens an HTTP/2 or TLS connection to a Node.js server.
  2. The server starts a response or a deferred callback (a file stream, an SNI lookup, a buffered write).
  3. The peer resets the stream, closes the socket, or sends an edge-case frame at the wrong moment.
  4. Native code frees the stream or socket state, but a pending write or callback still references it.
  5. Result: a crash (denial of service) or stale heap memory sent back to the peer.

The HTTPS bug, CVE-2026-123864, is a re-entrancy flaw. Per the advisory, a zero-length TLS write re-enters the HTTP parser while it is already running. The advisory says this can expose memory from other connections, “including TLS private keys”. Cleartext node:http is not affected by that one.

Triage step: search your own code for the APIs in the table.

grep -rnE "http2\.create(Secure)?Server|respondWith(File|FD)|altsvc|flushHeaders|addContext|SNICallback|OCSPRequest" src/

What should developers do right now?

  1. Detect. Run node --version on every host, container and CI runner. The official is-my-node-vulnerable tool can automate this once its database includes this release.
  2. Patch. Move to 22.23.5, 24.22.3 or 26.13.1. Example: nvm install 24.22.3, or pin FROM node:24.22.3 in Dockerfiles. Our Node.js 24 LTS upgrade guide covers line jumps.
  3. Restart. Running processes keep the old runtime, so restart services and rebuild images and single executable apps.
  4. Verify. Run the checker below in each environment and fail the deploy on a non-zero exit.
  5. Mitigate if you cannot patch today. SecurityOnline suggests terminating HTTP/2 at a proxy in front of Node.js. Also review per-host client-certificate rules.

A patch checker we ran

We wrote this small script and ran it in our sandbox on Node.js v22.23.4. The fixed versions come straight from the advisory.

// check-node-patch.mjs
const FIXED = { 22: [22, 23, 5], 24: [24, 22, 3], 26: [26, 13, 1] };
const [maj, min, pat] = process.versions.node.split('.').map(Number);
const fix = FIXED[maj];
if (!fix) {
  console.log(`Node ${process.versions.node}: no fix on this line - move to 22.x, 24.x or 26.x`);
  process.exit(2);
}
const patched = min > fix[1] || (min === fix[1] && pat >= fix[2]);
console.log(`Node ${process.versions.node}: ${patched ? 'PATCHED' : 'VULNERABLE - upgrade to ' + fix.join('.')}`);
process.exit(patched ? 0 : 1);

Raw output from our run:

$ node --version
v22.23.4
$ node check-node-patch.mjs
Node 22.23.4: VULNERABLE - upgrade to 22.23.5
$ echo $?
1

We also tested the comparison on nine version strings: 22.23.5, 22.24.0, 24.22.3 and 26.13.1 passed; 22.23.4, 24.22.2 and 26.13.0 failed.

Interview questions this update prepares you for

1. How can a garbage-collected runtime like Node.js have a use-after-free?

The garbage collector only manages JavaScript objects. Node.js also runs native C and C++ code: the llhttp parser, nghttp2, OpenSSL bindings and zlib. That code frees memory by hand. If a native stream is freed while a pending write still points to it, you get a use-after-free. Memory safety is a property of each layer, not of the language you type.

Follow-up they may ask: How would you reduce this risk in native addons you maintain?

2. What is a re-entrancy bug, and why is it dangerous in parsers?

Re-entrancy happens when a function is called again before its first call finishes. Parsers keep internal state such as buffer offsets and pointers. If a callback triggers the parser a second time mid-parse, both calls mutate the same state. The outer call then resumes with pointers that no longer match the buffer. Fixes include re-entrancy guards or queuing work until the current call returns.

Follow-up they may ask: How does the JavaScript event loop help or hurt here?

3. Why does HTTP/2 need per-session memory limits?

HTTP/2 multiplexes many streams over one TCP connection. One client can open lots of streams, queue data, or send tiny frames cheaply. If the server does not charge all buffered data to a session budget, a small amount of attacker traffic can hold large amounts of server memory. That is an amplification problem. Node.js exposes maxSessionMemory for this; one bug here was data escaping that accounting.

Follow-up they may ask: How does HTTP/2 flow control differ from TCP flow control?

4. How does SNI work, and how can it break mutual TLS?

Server Name Indication lets a client say which hostname it wants during the TLS handshake. The server then picks a certificate and policy for that host. With mutual TLS, each host may require client certificates from a different CA. If a host’s context silently falls back to a default CA, or renegotiation lets a client switch hostnames while keeping its earlier authentication, the stricter host’s policy is bypassed.

Follow-up they may ask: Why do many teams disable TLS renegotiation entirely?

5. Is a crash on a failed assertion a good design?

Failing fast protects integrity: an assertion stops the process before corrupted state spreads. But if a remote client can reach that assertion, it becomes a denial-of-service switch. Validate untrusted input, handle expected protocol errors gracefully, and keep assertions for truly impossible states. Run several instances with supervisors so one crash is not an outage.

Follow-up they may ask: How would you design graceful degradation for a single bad connection?

The NexGismo verdict: My recommendation: treat this as a same-week patch for anything serving HTTP/2 or HTTPS directly from Node.js. Do not wait for CVSS scores to appear. If your proxy already terminates TLS and HTTP/2, your exposure is smaller, but the upgrade is still cheap.

For context on this Node.js security release’s AI-found bugs, VulnCheck counted 442 CVEs attributed to Anthropic this year, with two known exploited. Anthropic documents its coordinated disclosure page. If you also lock down file access with flags, read our Node.js Permission Model gotchas next.

Frequently Asked Questions

Which Node.js versions fix the November 2026 vulnerabilities?

The fixed releases are Node.js 22.23.5, 24.22.3 and 26.13.1, per the official advisory. Any earlier patch on those lines is affected by at least some of the 16 CVEs. Older lines such as 20.x are not listed as receiving fixes, so the safe move is to upgrade to a patched supported line.

Do I need to restart Node.js after upgrading?

Yes. A running process keeps the old runtime in memory, so installing a new binary does nothing until the process restarts. Restart every service, rebuild container images that pin an older Node.js tag, and check CI runners too. Confirm each host with node –version after the restart.

Is my app affected if I only use plain HTTP?

Partly. The HTTPS memory-disclosure bug, CVE-2026-123864, does not affect cleartext node:http according to the advisory. But one high-severity HTTP/2 crash, CVE-2026-123863, works over both TLS and cleartext. Proxy credential leaks and Permission Model issues are also unrelated to TLS. Upgrading is still the only listed fix.

Are these Node.js vulnerabilities being exploited?

The Node.js advisory does not report exploitation in the wild. As of November 11, 2026, SecurityOnline reported no public exploit and none of the CVEs in CISA’s Known Exploited Vulnerabilities catalog. Several bugs are reachable by unauthenticated clients, so treat that as a reason to patch quickly, not to wait.

Conclusion

This Node.js security release is unglamorous but important. The bugs sit in the HTTP/2, HTTPS and TLS code that most servers rely on. The fix is simple: upgrade, restart, verify. Use the triage table to judge urgency and the checker to prove each environment is patched. Then harden the rest of your pipeline with our guide to npm supply chain defense layers. Subscribe to NexGismo for the next security update worth acting on.

Sources

Exit mobile version