← Back to Blog
Hot TopicOn This Site

Node.js Security Release (November 2026): How to Fix the 16 CVEs in 22.23.5, 24.22.3 and 26.13.1, Step by Step

On 11 November 2026 Node.js shipped fixes for 16 vulnerabilities (7 high) across the 22.x, 24.x and 26.x lines, mostly in HTTP/2 and TLS: remote crashes, heap memory sent to the peer, and client-certificate bypasses. Here is who is actually exposed, the fixed versions, how to upgrade servers, Docker images, CI and PM2 safely, what to do if you are still on Node 20, and the stopgap if you cannot patch today.

·10 min read

On Wednesday 11 November 2026, the Node.js project released security fixes for 16 vulnerabilities across every supported release line: 7 rated high, 6 medium and 3 low. Most of the serious ones are in HTTP/2 and TLS handling, and the worst outcomes are an unauthenticated remote crash, a use-after-free that can send another connection's heap memory to the client, and ways around client-certificate (mTLS) checks. The fixed versions are Node.js 22.23.5, 24.22.3 and 26.13.1. If your Node process speaks HTTP/2 or terminates TLS itself, upgrade today. If it sits behind Nginx or a load balancer that terminates TLS, you have more breathing room, but you should still upgrade this week, because some of the fixes are on the client side. And if you are still on Node 20, there is no fix coming for you at all.

I'm Kunal Vohra, a fractional CTO and a security researcher and cybersecurity advisor. Node.js runs a huge share of startup backends: API servers, Next.js apps, workers, CLIs, CI jobs, serverless functions. This is the second Node.js security release in three weeks (the October one fixed the Brotli bug some outlets call "Node2Shell"), so here is what changed, how to tell whether it matters for your stack, and a patch routine you can run in under an hour.

What the November 2026 Node.js release fixes

The official advisory, "Wednesday, November 11, 2026 Security Releases" on nodejs.org, lists 16 CVEs. Node.js did not publish CVSS scores in the advisory, only high, medium and low labels, and it does not say that any of these are being exploited.

The seven high-severity issues:

  • CVE-2026-123863, HTTP/2 remote abort. An unauthenticated client can trip an internal assertion when an HTTP/2 session is torn down and crash the process. Node.js describes it as a variant of the 2024 bug CVE-2024-27983. Affects 24.x and 26.x.
  • CVE-2026-123864, HTTPS re-entrancy in the HTTP parser. A zero-length TLS write can re-enter llhttp, causing a use-after-free and an out-of-bounds heap read that can leak memory into a response body. Plain node:http without TLS is not affected. Affects 22.x, 24.x and 26.x.
  • CVE-2026-123865, HTTP/2 sessions that never clean up. A protocol error during connection shutdown leaks memory and file descriptors permanently. Node.js calls it an incomplete fix of an earlier CVE. Affects all three lines.
  • CVE-2026-123866, freed memory sent to the peer. During HTTP/2 stream teardown, a use-after-free can send freed memory, including data from other connections, back to the client. Affects all three lines.
  • CVE-2026-126051, TLS server crash via deferred handshake callbacks. Servers using SNICallback, OCSP or session resumption callbacks can be crashed by an uncaught exception. Affects 24.x and 26.x.
  • CVE-2026-123872, TLS 1.2 renegotiation changes the server name. A client can change the SNI server name during renegotiation and bypass client-certificate authentication. Affects all three lines.
  • CVE-2026-123874, HTTP/2 use-after-free in respondWithFile(). Only reachable if your app serves files with respondWithFile() or respondWithFD(). Affects 24.x and 26.x.

The medium ones include a one-byte heap overflow in session.altsvc() (CVE-2026-123828), an mTLS fail-open when per-host SNI contexts only override the CA (CVE-2026-123867), unbounded HTTP/2 memory that maxSessionMemory does not catch (CVE-2026-123868), proxy credentials leaking into ERR_PROXY_INVALID_CONFIG error messages (CVE-2026-123871), a certificate validation bypass in https.Agent through TLS session reuse across different policies (CVE-2026-123877), and a server crash when someone cancels a respondWithFile() download (CVE-2026-123875).

The low ones are in the experimental Permission Model and zlib: a recursive fs.watch that leaks the names of denied files on macOS and Windows (CVE-2026-123829), an uncatchable assertion in zlib (CVE-2026-123862), and a wildcard file-system over-grant. One small inconsistency to know about: the advisory lists that last one as CVE-2026-106071, while the 24.22.3 release notes list CVE-2026-123873 ("permission: check heap snapshot destination") instead. It does not change what you need to do.

The release also updates bundled dependencies: llhttp on all three lines, undici on 24.x and 26.x, and SQLite on 22.x and 24.x. The 24.22.3 release notes list llhttp 9.4.4, undici 7.30.2, SQLite 3.54.1 and Brotli 1.2.1.

A detail worth noticing: five of the sixteen findings are credited to Chris Rohlf "in collaboration with Claude and Anthropic Research", and one to Trail of Bits (OpenAI). The October release credited the Brotli bug to OpenAI Codex Security. AI-assisted bug hunting is now feeding the patch queue of the runtime most startups depend on, which is the same pattern I wrote about in OpenAI's 948 Linux root exploits. Expect more frequent releases, not fewer.

Is this you? A five-minute check

Severity labels are a starting point. What matters is how your Node processes are exposed. Work through these in order.

1. Which versions are you running? Anything below 22.23.5, 24.22.3 or 26.13.1 on its line is affected. Check every place Node runs, not just your laptop:

# On a server or in CI
node --version
node -p "process.versions.llhttp"

# Inside a container image you deploy
docker run --rm your-registry/your-api:latest node --version

# Find the base images in your repos
grep -rn "FROM node" --include=Dockerfile* .

2. Does Node terminate TLS or speak HTTP/2 itself? Most of the high-severity bugs live here. If your Node app listens directly on 443, creates an https or http2 server, or uses mTLS, you are in the most exposed group. Search your code:

grep -rnE "http2\.create(Secure)?Server|https\.createServer|tls\.createServer|SNICallback|requestCert|respondWith(File|FD)|altsvc" --include=*.{js,ts,mjs,cjs} src/ server/ 2>/dev/null

Then check what is actually listening on the machine:

sudo ss -ltnp | grep node

If Node only listens on localhost:3000 (or similar) and Nginx, Caddy, a cloud load balancer or Cloudflare terminates TLS and forwards plain HTTP/1.1, the server-side HTTP/2 and TLS bugs are not reachable from the internet. That is the common setup for Next.js and Express apps on a VPS, and it is a real reduction in risk, not a reason to skip the upgrade.

3. Does Node make outbound HTTPS calls with custom agents or a proxy? The https.Agent session reuse bug (CVE-2026-123877) and the proxy credentials leak (CVE-2026-123871) are client-side. A reverse proxy in front of your app does nothing for them. If you build agents with different certificate policies, call internal services with private CAs, or configure an outbound proxy with credentials in the URL, these apply to you.

4. Are you on Node 20 or older? Node 20 ("Iron") is marked end-of-life on nodejs.org; its last release was on 24 March 2026, and the advisory states plainly that end-of-life versions are always affected when a security release happens. Node 25 is end-of-life too. There is no patched Node 20. The fix is a major-version upgrade.

The line I'd put in front of any founder: a reverse proxy can shield you from a server bug, but it cannot upgrade the runtime you forgot you were running.

How to fix it, step by step

Step 1: Make a list of every Node runtime

Servers, containers, CI runners, background workers, cron boxes, serverless functions, internal tools, and the version pinned in .nvmrc, engines in package.json, and your Dockerfiles. The fix takes minutes per place; finding the places is the slow part.

Step 2: Upgrade servers

If you installed Node with nvm:

nvm install 24.22.3
nvm alias default 24.22.3
node --version   # v24.22.3

If you installed it from the NodeSource apt repository on Debian or Ubuntu (use the line you are on, 22.x, 24.x or 26.x):

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

If you are on Node 20, do not try to patch in place. Pick 24.x (the active LTS line most teams should be on) or 22.x, run your test suite against it first, and then switch. Node 22 to 24 and 20 to 24 are both major jumps; treat them as a normal dependency upgrade with a staging deploy, not a hotfix.

Step 3: Restart every Node process

Upgrading the binary does nothing for processes already running. With PM2 there is a trap: the PM2 daemon itself runs on the old Node until you restart it, and apps started by it can keep the old interpreter path, especially with nvm. One way to do it cleanly:

pm2 save
pm2 kill
pm2 resurrect
pm2 show your-app | grep -i "node.js version"

If your ecosystem file pins an interpreter path (for example an nvm path with the old version number in it), update that path first. With systemd, sudo systemctl restart your-service and then check node --version as the service user. Test this sequence on staging before you run it on production.

Step 4: Rebuild container images

Bump the base image tag and rebuild with --pull so you do not reuse a cached layer with the old Node:

FROM node:24.22.3-bookworm-slim
docker build --pull -t your-registry/your-api:node-24.22.3 .
docker run --rm your-registry/your-api:node-24.22.3 node --version

Pinning an exact patch version makes upgrades visible in code review. If you use a floating tag like node:24-slim, a rebuild with --pull picks up the fix once the official images are published, but you have no record of which version you actually shipped. Check that the exact tag exists on Docker Hub before you merge.

Step 5: Update CI and local development

Bump node-version in your CI configuration (for example actions/setup-node) and the version in .nvmrc. Self-hosted runners need the same server upgrade as Step 2. CI runners rarely serve HTTP/2 to strangers, so they are lower risk, but keeping CI and production on the same Node version saves you from "works in CI, crashes in prod" a month from now.

Step 6: Check managed platforms

If you run on a platform that manages the Node runtime for you (serverless functions, PaaS), check your provider's status page or runtime changelog for when they rolled out 22.23.5, 24.22.3 or 26.13.1, and whether you need to redeploy to pick it up. Do not assume; some platforms only update the runtime on the next deploy.

Step 7: If you cannot upgrade today, reduce exposure

These are stopgaps, not fixes:

  • Put TLS and HTTP/2 termination in front of Node. Let Nginx, Caddy or your load balancer terminate TLS and speak HTTP/1.1 to Node on localhost. This removes direct exposure to the server-side HTTP/2 and TLS bugs.
  • Disable HTTP/2 on Node directly if you enabled it only for performance and a proxy can do that job.
  • Enforce client certificates at the proxy if you rely on mTLS, rather than in Node's SNICallback or requestCert logic, until you are patched.
  • Watch for crash loops. Several of these bugs crash the process. Alert on unusual restart counts from PM2, systemd or your orchestrator.

None of these help with the client-side bugs or with an end-of-life runtime. Upgrade anyway.

Step 8: Verify

On every host and image, node --version should show 22.23.5, 24.22.3, 26.13.1 or later. Record the date you patched in your security log or incident tracker. It is the evidence an investor or enterprise customer will ask for later.

Did you miss October too?

The October 21, 2026 Node.js security release fixed ten vulnerabilities, including CVE-2026-111497, a Brotli decoder out-of-bounds write that Node.js says can lead to remote code execution when an app decompresses attacker-controlled data with node:zlib. Express 5 decompresses Brotli request bodies by default, and fetched responses can be Brotli-encoded too, so this one reaches more apps than the name suggests. October's fixed versions were 22.23.4, 24.22.1 and 26.12.1.

Several outlets (Cyber Kendra, Convika and Brandefense) report that CISA added CVE-2026-111497 to its Known Exploited Vulnerabilities catalogue on 27 October. I could not open the CISA catalogue to confirm that directly, and Node.js itself has not said it is exploited, so treat that as reported rather than confirmed. Either way, the November versions include the October fixes. Upgrading to 22.23.5, 24.22.3 or 26.13.1 closes both.

What this means for startups

Two Node.js security releases in three weeks, with AI-assisted researchers credited on several findings, is the new normal. The runtime under your product is getting examined faster than ever, which is good for everyone, as long as your team can absorb a patch without a fire drill.

The teams that close this in a morning have three things: an inventory of every place Node runs, base images pinned to exact versions so upgrades show up in a pull request, and an owner who checks the Node.js security page when a release is announced. If you read my posts on the APT flaw and the Next.js CVE-2026-96889 fix, you will recognise the pattern: the patch is quick, finding every place that needs it is slow. My startup security checklist puts that inventory near the top for that reason.

Here is what I'd do as a CTO this week:

  1. Today: patch anything where Node terminates TLS or serves HTTP/2 to the internet, and anything using mTLS.
  2. This week: patch everything else, rebuild images, bump CI and .nvmrc.
  3. This month: move every service off Node 20 and set a calendar reminder for the next end-of-life date of the line you land on.
  4. Ongoing: subscribe the person who owns infrastructure to the Node.js security announcements, and make "runtime version" a field in your service inventory.

If nobody on your team owns this, that is the real gap. A technical advisor can set up the inventory, image pinning and patch routine with your engineers in a few sessions; a fractional CTO owns it on an ongoing basis along with the rest of your security posture.

Frequently asked questions

What versions fix the November 2026 Node.js vulnerabilities? Node.js 22.23.5, 24.22.3 and 26.13.1, released on 11 November 2026. Anything older on those lines is affected. End-of-life lines such as Node 20 and Node 25 get no fix.

Is Node 20 affected by the November 2026 Node.js security release? Node.js says end-of-life versions are always affected when a security release happens, and Node 20 is end-of-life, so assume yes. There is no patched Node 20 release; upgrade to 24.x or 22.x.

Are these Node.js vulnerabilities being exploited? The Node.js advisory does not say any of the 16 November issues are exploited. Separately, the October Brotli bug CVE-2026-111497 has been reported by several security outlets as added to CISA's KEV catalogue, which is another reason to upgrade now.

I run Next.js or Express behind Nginx. Am I safe? Safer, not safe. If Nginx terminates TLS and talks plain HTTP/1.1 to Node on localhost, the server-side HTTP/2 and TLS bugs are not reachable from outside. The client-side bugs (outbound HTTPS agents, proxy credentials) and the October Brotli issue still apply, so upgrade this week.

Do I need to restart after upgrading Node.js? Yes. Running processes keep the old binary until they restart. With PM2, restart the daemon itself (for example pm2 save, pm2 kill, pm2 resurrect) and confirm the version with pm2 show.

How do I check the Node.js version inside a Docker image? Run docker run --rm your-image node --version. If it is older than the fixed version, bump the FROM node: tag and rebuild with docker build --pull.

If you're not sure how many places in your stack run Node, or you want an upgrade routine that makes the next release boring, book a 30-minute call. Bring your Dockerfiles and your PM2 config; that's usually where the old versions hide.

Sources

Written By

Kunal Vohra

Kunal Vohra

Technical Co-Founder & Fractional CTO

I've co-founded 6+ startups across India, the UAE, and the US, spanning AI, Web3, fintech, and cybersecurity. I write about the technical and strategic decisions that determine whether a startup thrives or stalls.

Comments

Loading comments…

Enjoyed this article?

More writing on AI, Web3, and building startups.