Safeguard
Vulnerability Analysis•

Nine undici Advisories Ahead of Node.js's 21 October Security Release

undici fixed nine issues on 14 and 15 Oct, two of them reachable through plain fetch(). Node.js has security releases due 21 Oct. Here is what to patch and where.

Safeguard Security Team
6 min read

On 14 and 15 October 2026 the undici maintainers published nine security advisories and released undici 6.29.1, 7.30.1 and 8.12.2. On 14 October the Node.js project pre-announced security releases for the 26.x, 24.x and 22.x lines, due on or shortly after Wednesday 21 October, with a highest severity of High. The pre-announcement doesn't list the issues.

undici matters twice over. It is a direct dependency in many Node.js services, and it is the HTTP client behind Node's global fetch() and WebSocket. Most of the nine advisories need a specific undici feature to be reachable. Two of them reach code that does nothing more than call fetch().

What's affected

The two that need no special configuration:

  • CVE-2026-109869, High 7.5. fetch() crashes the Node.js process when a malicious server returns more than five content codings and closes the connection before the body. undici rejected such responses but had already created an internal stream with no error listener. The advisory says this happens "even when the application correctly catches the fetch() rejection." Affected: 6.23.0 and later on 6.x, 7.18.0 and later on 7.x, all of 8.x before the fixes.
  • CVE-2026-87018, High 7.5. A TLS 1.2 server renegotiates after the handshake and presents a second CA-trusted certificate that doesn't match the hostname. Node destroys the socket with ERR_TLS_CERT_ALTNAME_INVALID, and undici hit an assertion that turned the error into a process crash. The advisory notes this needs no CA compromise: the attacker controls the endpoint and holds two ordinary valid certificates. Affected from 4.2.1.

The ones gated by features:

CVESeverityReachable only if you
CVE-2026-109383High 7.4Pass a function such as checkServerIdentity in the tls option of Agent (certificate pinning). The function was silently dropped.
CVE-2026-109829High 7.4Compose redirect() before cache() with a shared cache on an originless Agent
CVE-2026-109855High 7.5Open WebSockets over HTTP/2 on undici 8.11.0 or 8.11.1
CVE-2026-109841Moderate 5.9Pin fetch() responses with Subresource Integrity using uppercase tokens like SHA256-
CVE-2026-109924Moderate 5.9Keep an EventSource open to an untrusted server
CVE-2026-109932Moderate 5.9Use the WebSocket client against an untrusted peer. Automatic PONG replies could queue without bound under backpressure.
CVE-2026-87029Moderate 5.9Compose the decompress interceptor with dump or another handler that throws

Fixed versions are 6.29.1, 7.30.1 and 8.12.2 for all but one. The HTTP/2 WebSocket crash was a regression only in 8.11.0 and 8.11.1 and is fixed in 8.11.2. The SRI, cache-redirect and decompress issues don't affect 6.x.

How to check if you're exposed

Check both copies of undici: the one in your dependency tree and the one inside Node.

npm ls undici --all
node -p "process.versions.node + ' bundles undici ' + process.versions.undici"

Then decide which advisories your code can reach.

# Global fetch or undici request calls to hosts you don't control
grep -rnE "\bfetch\(|undici" src/ | grep -v test | head -40

# Certificate pinning through the tls option (CVE-2026-109383)
grep -rn "checkServerIdentity" src/

# Interceptor compositions (CVE-2026-109829, CVE-2026-87029)
grep -rnE "interceptors\.(cache|redirect|decompress|dump)" src/

# SRI on fetch (CVE-2026-109841)
grep -rn "integrity:" src/

The question for the two default-path bugs is simple: does this service ever call fetch() on a URL an outsider can influence or a server an outsider can run? Webhook senders, link previewers, OAuth and OIDC discovery, image proxies and AI agents that browse the web all qualify. A service that only calls your own internal APIs over TLS 1.3 is much harder to hit.

What to do now

  1. Upgrade direct undici dependencies to 6.29.1, 7.30.1 or 8.12.2, and confirm with npm ls undici --all that no older copy remains in the tree.
  2. Plan a Node.js upgrade for 21 October. Global fetch() and WebSocket use the undici bundled with Node, which npm install can't change. Read the release notes when they ship, and roll the new Node.js patch into base images and CI runners.
  3. Apply the interim workarounds from the advisories where they fit. For pinning, pass TLS options through connect instead of tls. For the renegotiation crash, restrict outbound TLS to 1.3 where your targets support it. For SRI, use lowercase algorithm tokens. For the cache issue, compose cache() before redirect().
  4. Treat process crashes as a signal. Several of these bugs end in an uncaught exception. Alert on unexpected Node.js restarts in services that fetch external URLs.
  5. Rebuild containers. A base image with an older Node.js keeps the old bundled undici no matter what your lockfile says.

Why it matters

The split between "library you installed" and "library your runtime ships" catches teams out. Upgrading the undici package in package.json does nothing for code that calls the global fetch(). That code only gets fixed when the runtime does, which is why the Node.js release on 21 October matters as much as the npm releases on 15 October.

It also shows how much of a client library's risk comes from the server side. undici's own threat model says it does not trust data from the remote end of a connection. Every service that fetches a URL supplied by a user, a webhook or a model is putting that model to the test.

Try it yourself

Pick one Node.js service. Run the two version commands above and write down both undici versions. Then list every outbound fetch() target and mark each as "we control the server" or "someone else can". The second list is your reachable surface for CVE-2026-109869 and CVE-2026-87018.

Click through it at your own pace, or open it full screen.

Quick check

Does upgrading the undici package fix a service that only uses the global fetch()?

No. Global fetch() uses the copy of undici bundled with Node.js. That copy changes only when you upgrade Node.js itself.

Which two advisories are reachable without any special undici configuration?

CVE-2026-109869, the content-encoding crash in fetch(), and CVE-2026-87018, the TLS 1.2 renegotiation crash. Both need only an outbound request to a server the attacker controls.

What is the advisory's workaround for the dropped checkServerIdentity callback?

Pass the TLS options through connect instead of tls. For proxied EnvHttpProxyAgent destinations, use requestTls or proxyTls.

Sources

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.