Node.js patches 16 CVEs: HTTP/2 crashes and an HTTPS bug that leaks TLS keys

Node.js patches 16 CVEs: HTTP/2 crashes and an HTTPS bug that leaks TLS keys

On 11 November the Node.js project shipped security releases for all three supported lines: 22.23.5 (Jod), 24.22.3 (Krypton) and 26.13.1 (Lithium). The batch covers 16 CVEs. Seven are rated High, six Medium and three Low, and the bundled llhttp, undici and sqlite dependencies got updated along the way.

The serious problems are in Node's own server code for HTTP/2, HTTPS and TLS. One bug lets a client with no credentials kill a default HTTP/2 server. Another lets a client read memory that belongs to other connections, and that includes TLS private keys. The project reports no known attacks, and CISA hasn't added any of them to its KEV list. The advisory also lists no workaround. Either you upgrade or you stay exposed.

The bugs we'd read first

CVE-2026-123863 (CVSS 8.2, High) is a reachable assertion in HTTP/2 session teardown. What triggers it is pretty mundane: a stock http2 server whose handler sends a response before the client has finished sending the request body. A remote client can use that to take the whole process down, and it works over TLS and over cleartext. It's a variant of CVE-2024-27983 that slipped past the earlier fix. Affected: 24.x from 24.22.0 on, and 26.x from 26.9.0 on.

CVE-2026-123864 is the one that made me put my coffee down. It's a re-entrancy bug in Node's HTTPS layer, and an attacker who never logs in can use it to read data from other people's connections. That can mean their requests, or it can mean your server's TLS private key. It affects 22.x, 24.x and 26.x. The attacker needs a particular handler shape: res.flushHeaders() called before the request body has finished, then res.end() with a non-empty chunk later on. On top of that, some route has to echo or store a request body, because that's how the leaked bytes get back to the attacker. Plain node:http without TLS is not affected.

CVE-2026-123866 is a use-after-free in HTTP/2 stream teardown. It can send freed memory, or another connection's response data, to the peer. All three lines are affected.

CVE-2026-123872 is quieter but nasty if you do mTLS. During TLS 1.2 renegotiation a client can change the servername and carry an existing client-certificate authentication over to a host that has stricter per-host client-certificate rules. If one Node process serves several hostnames with different certificate requirements, read this one twice.

Then there's CVE-2026-126051, a TLS server crash that can be triggered remotely. It affects 24.x and 26.x servers that use SNICallback, OCSPRequest, newSession, resumeSession or server.addContext().

End-of-life lines get nothing. If you're still running 20.x or 25.x, this release doesn't fix anything for you.

Who found all this? Chris Rohlf, working with Claude and Anthropic Research, reported 123863, 123864 and several other issues in the release, and Matteo Collina wrote most of the fixes. My guess is that AI-assisted bug hunting means we'll see more of these big multi-CVE batches, not fewer. Plan your patch process for that.

Who is actually exposed

The group at risk is teams that terminate HTTP/2 or HTTPS inside Node itself. That's a smaller group than "everyone running Node", but it's bigger than most people assume.

When we build cloud-native apps for enterprise clients, Node usually sits behind a load balancer or reverse proxy that handles TLS and talks plain HTTP/1.1 to the app. In that setup the key-leak bug doesn't reach you, because cleartext node:http is out of scope. But in our Docker work we keep running into the other kind of service too: an admin API, a webhook receiver, a small internal tool where someone called https.createServer or http2.createSecureServer directly because it was faster than setting up a proxy. Nobody remembers those services when upgrade time comes around.

Also note that 123863 works over cleartext HTTP/2. If your services talk h2c to each other inside a cluster, the fact that TLS is handled upstream won't protect you from the crash.

Mobile teams should pay attention here as well. In our native iOS and Android projects the backend is often a Node API, and we've seen teams switch on HTTP/2 directly in Node for app traffic to cut latency. If that process can be crashed remotely, your users see spinners and failed requests while your crash reporting shows nothing wrong on the device side. It's a confusing incident to debug at 2am.

On the security side, the memory disclosure bugs worry me more than the crashes. A crash shows up in your monitoring within minutes. A leak doesn't page anyone. During our pentesting engagements for gaming studios, the worst findings were rarely the loud ones. They were the quiet reads nobody had a log line for. And from our DDoS work with travel-platform clients: when we configure Cloudflare or Akamai in front of an origin, the first thing we test is whether the origin is still reachable directly. Often it is. Your edge config won't help if an attacker can talk to the Node process without going through it.

What to do today

  1. Inventory every Node process, not just the main app. Run node -v inside each container image you deploy, including cron jobs and sidecars. A pinned base image tag won't update itself, so rebuild and redeploy.
  2. Upgrade to 22.23.5, 24.22.3 or 26.13.1, depending on your line. There's no config flag that makes this go away.
  3. Search your code for the HTTPS leak pattern: grep -rn "flushHeaders" . If you get hits in an HTTPS handler and some route echoes or stores request bodies, move that service to the front of the queue. If it was internet-facing, rotating its TLS key costs you little, even with no attacks reported.
  4. If you're on 20.x or 25.x, put the migration on this sprint's board. Leaving it for next quarter isn't an option anymore.
  5. Check that your origins only accept traffic from your CDN or load balancer.

None of this is glamorous work, and honestly the upgrade itself is usually the easy part. Finding the forgotten service that terminates its own TLS takes longer. If you want a sense of how we approach this kind of audit, our services overview and past work give you an idea, and our development team handles these runtime upgrades all the time.

If a Node service with its own TLS setup that nobody has touched since launch sounds familiar, let's talk.

http2nodejstech-newstlsvulnerability