Open actionable advisories and recorded vendor fixes. This public package view has no inventory attached and cannot establish whether your deployment is affected. A vendor fix never resolves your finding; verify your installed version and the source guidance.
Open advisories
55 actionable advisories, newest first. Withdrawn advisories and news are excluded. Coverage is partial.
Impact When an originless `Agent` composes the redirect and cache interceptors as `compose(redirect(), cache())` with a shared cache (`type: 'shared'`), the cache builds its key from the original request URL before the redirect handler changes the origin. The response produced after a redirect is then stored under the original key, even when the redirect crossed to a different origin. An attacker who controls the target of a redirect from a trusted URL can have their response cached under that trusted URL. A later caller requesting the trusted URL receives the attacker's body from the shared cache without either origin being contacted, allowing persistent cache poisoning. The same key confusion also discloses private data: when an authenticated request returns a `private, no-store` redirect to a user-specific resource, the final response is stored under the original URL and can be served to a later unauthenticated caller. The cache interceptor was introduced in undici 7.0.0, and…
Recommended action: Upgrade to 8.12.2 or 7.30.1 by release line, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
Impact undici's `Agent` passes its constructor options through a JSON-based deep clone (`JSON.parse(JSON.stringify(...))`) before forwarding them to each per-origin `Pool`. JSON cannot represent functions, so a caller-supplied `tls` option containing a `checkServerIdentity` callback is silently dropped before it reaches the TLS layer. As a result, a TLS peer whose certificate a custom `checkServerIdentity` was written to reject, but which passes Node's default hostname and chain checks, is silently accepted when the request is made through `Agent`. Because `Agent` is the default dispatcher behind `request`, `fetch`, and `setGlobalDispatcher`, this is the path most applications use. `EnvHttpProxyAgent` is also affected on its direct and `NO_PROXY` routes, which delegate to an internal `Agent`. Only applications that pass a function-valued `tls` option (such as a custom `checkServerIdentity` for certificate or public-key pinning) are affected. Passing the same options through…
Recommended action: Upgrade to 8.12.2, 7.30.1 or 6.29.1 by release line, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
Impact undici crashes the client process when a TLS 1.2 server renegotiates after the connection is established and presents a different, CA-trusted certificate whose hostname does not match the requested host. Node.js re-runs hostname verification on the renegotiated handshake and destroys the socket with `ERR_TLS_CERT_ALTNAME_INVALID`. undici's established socket error handler asserted that this error code could never occur, so the peer-controlled error became an uncaught `AssertionError` that terminates the Node.js process. Both the HTTP/1.1 and HTTP/2 paths are affected. A malicious or compromised HTTPS endpoint reached through undici or the global `fetch()` can crash the client with a single server-initiated renegotiation, taking down all in-flight requests and background work in the process. Only TLS 1.2 is affected, because TLS 1.3 does not support renegotiation. Exploitation does not require a CA compromise: the attacker controls the endpoint and can present two ordinary…
Recommended action: Upgrade to 8.12.2, 7.30.1 or 6.29.1 by release line, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
Impact undici's WebSocket client (including Node.js's bundled `globalThis.WebSocket`) can be driven to exhaust process memory by a malicious or compromised WebSocket server. For every PING frame received, the receiver automatically writes a PONG response to the socket and ignores the `false` return value from `socket.write()`, which is a backpressure signal, so a server that streams small PING frames while never reading the client's PONGs makes the outbound write queue and heap grow without bound until the Node.js process runs out of memory and terminates. The attack is remote and unauthenticated, needs only a normal WebSocket connection, and is asymmetric: small inbound PINGs produce a much larger retained outbound queue. Availability is the only impact. undici 5.x, 6.x, 7.x, and 8.x are affected; the WebSocket client was introduced in 5.15.0. Patches Upgrade to `6.29.1`, `7.30.1`, or `8.12.2`, which pause WebSocket frame parsing when the automatic PONG response hits socket…
Recommended action: Upgrade to 8.12.2, 7.30.1 or 6.29.1 by release line, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
Impact undici's `decompress` interceptor forwards decompressed response data to the downstream handler from zlib stream event callbacks without catching exceptions those callbacks may throw. undici's engine converts a synchronous throw from a downstream handler into a per-request failure, but that protection is not in place when the throw happens asynchronously from a zlib callback. As a result, a downstream handler that throws by design, for example the built-in `dump` interceptor which throws when a response exceeds its `maxSize`, escapes as an uncaught exception and terminates the Node.js process. A malicious or compromised HTTP server can crash any client that composes the `decompress` interceptor with `dump` (or another response handler that throws), by returning a small compressed body that decompresses to more than the configured limit. The compressed bytes on the wire are tiny, so only the decompressed size matters. If the application keeps the process alive with a global…
Recommended action: Upgrade to 8.12.2 or 7.30.1 by release line, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
Impact undici's experimental WebSocket client (enabled by default via `allowH2: true`) crashes the Node.js process when it connects to a malicious server over HTTP/2. If the server answers the WebSocket upgrade with a response that fails handshake validation, undici aborts the request, but the abort is a no-op because the request is already marked completed, so the underlying `ClientHttp2Stream` is left open with no error listener. When the server then destroys the connection, the orphaned stream emits an unhandled `error` and the process exits. A remote, unauthenticated server can therefore deny service to any client that opens a WebSocket to it over HTTP/2. undici 8.11.0 and 8.11.1 are affected; the regression was introduced in 8.11.0. Patches Upgrade to `8.11.2`. Workarounds Set `allowH2: false` to disable HTTP/2 for WebSocket connections, or avoid opening WebSocket connections to untrusted servers, until upgrading.
Recommended action: Upgrade to 8.11.2 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
Impact undici's fetch() crashes the Node.js process when a malicious server returns a response with more than five content codings and closes the connection before sending the body. undici rejects such responses (a content-encoding limit), but it created the internal response stream before that check and returned without attaching an error listener or aborting the request. The early close then surfaces a content-length mismatch on that orphaned internal stream, which Node.js treats as an unhandled error and terminates the process. A remote, unauthenticated server can trigger this with a single response, even when the application correctly catches the fetch() rejection. undici 6.x, 7.x, and 8.x are affected. Patches Upgrade to 6.29.1, 7.30.1, or 8.12.2. undici now validates the content-encoding chain before creating the internal body stream and aborts the response when the limit is exceeded, so no error can surface on an orphaned stream. Workarounds None.
Recommended action: Upgrade to 8.12.2, 7.30.1 or 6.29.1 by release line, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
Impact undici's EventSource client can be driven to exhaust process memory by a malicious or compromised Server-Sent Events peer. By sending millions of tiny completed data: fields with no blank event separator, or a single unfinished line split across many chunks, the parser retains a growing amount of per-field and per-chunk state. The byte-based maxEventSize and maxResponseSize limits do not bound that retained state, and maxResponseSize is enforced on the compressed body before decompression, so a small compressed response can expand into enough retained memory to terminate the process. The application only needs to maintain an EventSource connection to an untrusted peer, which controls only the response. Availability is the only impact. Patches Upgrade to 6.29.1, 7.30.1, or 8.12.2, which bound the retained EventSource parser state (the number of data fields and buffered chunks, the unfinished-line length, and per-field byte totals) independently of the byte limits. Workarounds…
Recommended action: Upgrade to 8.12.2, 7.30.1 or 6.29.1 by release line, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
Impact undici's fetch() verifies Subresource Integrity (SRI) metadata by looking up the algorithm token in a lowercase-only set, but the SRI specification defines a valid token by its ASCII-lowercase form. A correct but non-lowercase token such as SHA256-... or Sha256-... is therefore treated as unknown and skipped. When no recognized algorithm remains, undici treats the integrity list as empty and accepts the response, so a server that returns a body different from the pinned digest passes the check. An application that pins a response with a valid uppercase or mixed-case SRI token receives attacker-controlled bytes with no integrity error. The attacker needs only to control the response body, not the application's integrity metadata. The issue affects response integrity only. The regression was introduced in undici 7.15.0; releases 7.14.0 and earlier lowercase the token and are not affected. Patches Upgrade to 7.30.1 or 8.12.2. undici now normalizes the algorithm token to ASCII…
Recommended action: Upgrade to 8.12.2 or 7.30.1 by release line, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
Impact undici's RetryHandler can leave a response body pending indefinitely. When a retried request receives a non-retryable response after a truncated one, the original response.body held by the application is never settled, so reads such as response.body.text() hang and bodyTimeout does not fire. A malicious server can repeat this to accumulate pending promises and streams, leading to denial of service. Patches Patched in undici v7.29.1 and v8.10.2. Workarounds Impose an independent request deadline and destroy the response body when it expires. bodyTimeout alone does not prevent this.
Recommended action: Upgrade to 8.10.2 or 7.29.1 by release line, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
Impact Undici's interceptors.retry() can resume a request after a partial response and append the resumed bytes to an already partially delivered body, while the application still receives the original response's status and headers. When that response carried a Content-Length, the application can receive a longer body. Applications that forward Undici's status, headers, and body downstream without recalculating framing, for example proxy or gateway applications, may emit a response whose body exceeds the forwarded Content-Length, and the excess bytes can be read as the start of a subsequent HTTP response (downstream response splitting or desynchronization). For example, a 404 Not Found with Content-Length: 2 that sends one byte then closes can be resumed with an open-ended Range request, and the resumed 206 Partial Content bytes are appended, so the application receives more than two body bytes while still seeing Content-Length: 2. The bug requires interceptors.retry() enabled, an…
Recommended action: Upgrade to 8.10.2, 7.29.1 or 6.28.1 by release line, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
Impact The undici WebSocket client throws an uncaught TypeError during the opening handshake when a server's 101 response includes a Sec-WebSocket-Protocol header that the client never requested. The throw occurs in a queueMicrotask callback with no surrounding try/catch, so it propagates as an uncaught exception and terminates the Node.js process. This is a remote, unauthenticated denial of service against any application that opens a WebSocket to an attacker controlled or compromised server, or over a plaintext ws:// connection subject to a machine-in-the-middle. It affects the default new WebSocket(url) usage, where no subprotocol is requested. Per RFC 6455 section 4.1, an unrequested subprotocol must fail the connection, not crash it. All releases starting at undici 6.7.0 are affected. Patches Upgrade to undici 6.28.1, 7.29.1, or 8.10.2. Workarounds No workaround is available. The fix must be applied through an upgrade.
Recommended action: Upgrade to 8.10.2, 7.29.1 or 6.28.1 by release line, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
Impact The interceptors.decompress() interceptor decompresses HTTP response bodies according to the untrusted Content-Encoding header. The number of decompression layers is capped at 5, but the total decompressed output size is not bounded and there is no option to limit it. A malicious or faulty upstream can return a small compressed payload (a compression bomb) that expands to hundreds of megabytes or gigabytes in client memory, exhausting memory and causing the Node.js process to crash or become unresponsive. Any application using the decompress interceptor to read responses from untrusted or compromised upstreams is affected. Patches Upgrade to 7.29.1 or 8.10.2. The interceptor now accepts a maxSize option (default 64 MiB) and rejects responses whose decompressed output exceeds it with a ResponseExceededMaxSizeError. Workarounds Once upgraded, set a conservative maxSize on the interceptor. Before upgrading, avoid using interceptors.decompress() with untrusted upstreams, or apply…
Recommended action: Upgrade to 8.10.2 or 7.29.1 by release line, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
Impact undici's interceptors.cache() does not handle Set-Cookie in the cache path. In shared-cache mode (type: 'shared', the default), a cacheable response (for example Cache-Control: public, max-age=...) carrying a Set-Cookie header is stored, and the stored Set-Cookie is re-served to a later caller that hits the same cache key. This exposes one user's cookie to another caller and lets an untrusted upstream inject cookies into cached responses served to all subsequent callers, violating RFC 6265 section 7.2 (a shared cache must not store cookies). Applications using the shared cache interceptor against untrusted or multi-user upstreams are affected. Private caches (type: 'private') are not affected. Patches Upgrade to 7.29.1 or 8.10.2. In shared-cache mode, undici no longer stores or re-serves responses containing Set-Cookie, including previously cached entries and revalidation paths. Workarounds Use a private cache (type: 'private') for per-user responses, or avoid caching…
Recommended action: Upgrade to 8.10.2 or 7.29.1 by release line, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
Impact undici's interceptors.dump() reads and discards response bodies up to a configurable maxSize. When a response declares a Content-Length that exceeds maxSize, the request is aborted cleanly. When a response is sent chunked (no Content-Length) and its body exceeds maxSize, it is not aborted: the interceptor ends the response early once the accumulated size reaches maxSize, and continued delivery from the parser triggers an internal assertion that is caught and turned into a request abort and connection tear-down. The application observes a misleading 200 with an empty or truncated body while the connection is disconnected. Any application using the dump interceptor against untrusted or misbehaving upstreams is affected. Patches Upgrade to 7.29.1 or 8.10.2. The dump interceptor now enforces maxSize on both the declared and the received body size, aborting the request with a RequestAbortedError instead of returning a truncated response. Workarounds None. Avoid using…
Recommended action: Upgrade to 8.10.2 or 7.29.1 by release line, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
Impact undici's BalancedPool passes its constructor options through a JSON-based deep clone (JSON.parse(JSON.stringify(...))) before forwarding them to each per-upstream Pool. JSON cannot represent functions, so a caller-supplied connect or tls option containing a checkServerIdentity callback (or a custom connector function) is silently dropped before it reaches the TLS layer. As a result, a TLS peer whose certificate a custom checkServerIdentity was written to reject, but which passes Node's default hostname and chain checks, is silently accepted when the request is made through BalancedPool. Client, Pool, Agent, and RoundRobinPool destructure connect/tls before the clone and are not affected. Only applications that use BalancedPool with a function-valued connect/tls option (such as a custom checkServerIdentity or connector) are affected. Patches Upgrade to 7.29.1 or 8.10.2. BalancedPool now preserves the connect and tls options outside the JSON clone, so custom TLS verification…
Recommended action: Upgrade to 8.10.2 or 7.29.1 by release line, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
Impact undici's interceptors.cache() documents that it caches only safe HTTP methods. However, its internal skip-list is built by subtracting the configured methods from the safe-methods set, so an unsafe method (POST, PUT, PATCH, DELETE) never lands in the skip-list and is looked up against the cache store. Combined with the storage gate (canCacheResponse) having no method check, a heuristically-cacheable response (for example a 404) with an explicit Cache-Control: max-age=... to an unsafe method is stored and replayed on a subsequent identical request. The application's state-changing request never reaches the origin, and undici serves a fabricated response from the cache instead. This occurs with the default configuration (methods: ['GET']), which the public API does not allow widening to unsafe methods, so no application misuse is required; an untrusted origin can trigger it purely through its own response headers. Patches Upgrade to 7.29.1 or 8.10.2. The cache interceptor no…
Recommended action: Upgrade to 8.10.2 or 7.29.1 by release line, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
Impact When interceptors.cache() or interceptors.deduplicate() is used with a dispatcher that does not carry a single authoritative origin, or when a request supplies its own origin, undici builds the cache and deduplication keys without the actual destination origin. If a cache store or interceptor instance is shared across more than one origin, otherwise-identical requests to different origins are keyed together. An attacker who controls the response from one origin can then have that response returned for a request to a different, trusted origin when the method, path, and relevant headers match. This allows cross-origin information disclosure and persistent cache poisoning, including chains such as JWKS cache poisoning where a token signed with an attacker-held key is accepted as belonging to a trusted issuer. Applications that share interceptors.cache() or interceptors.deduplicate() state across origins are affected. An Agent is not affected, because its dispatch options include…
Recommended action: Upgrade to 8.10.2 or later, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
Impact undici's WebSocketStream crashes the client process when a WebSocket connection is closed abruptly without a close handshake. On such an unclean close, the internal socket-close handler calls abort() on the writable stream even when the application holds a writer lock. Per the WHATWG Streams standard, aborting a locked stream returns a promise that rejects with a TypeError, and the handler discards that promise. The unobserved rejection surfaces as an unhandledRejection and, under Node.js's default behavior, terminates the process. A malicious or compromised WebSocket server can crash a client with a single connection teardown (a TCP reset, a proxy teardown, or a protocol-violating frame). Affected applications are those using the WebSocketStream API and writing through a writer, which is the standard way to write. All releases from undici 7.0.0 are affected. WebSocketStream was introduced in 7.0.0. Patches Upgrade to undici v7.29.1 or v8.10.2. Workarounds No workaround is…
Recommended action: Upgrade to 8.10.2 or 7.29.1 by release line, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
Impact undici's WebSocket client (including Node.js's bundled globalThis.WebSocket) crashes the entire Node.js process when a remote WebSocket peer sends a permessage-deflate compressed message that crosses the decompressed-payload size limit and then contains a malformed DEFLATE block. In lib/web/websocket/permessage-deflate.js, the size-limit cleanup calls removeAllListeners() on the internal zlib InflateRaw, removing its error listener, but leaves the stream running. The inflater then emits a ZDATAERROR with no listener attached, which Node.js treats as a fatal unhandled error event and terminates the process. Application error/close handlers on the public WebSocket cannot observe or prevent this, because the failing object is the internal InflateRaw. A malicious or compromised WebSocket server can crash a client with a single connection, unauthenticated and without any application mistake. The attack is asymmetric (about 130 KB on the wire expands past the limit) and can be…
Recommended action: Upgrade to 8.10.2, 7.29.1 or 6.28.1 by release line, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
Impact When an application passes a duck-typed blob-like body to undici's HTTP/1.1 dispatcher (via request(), stream(), pipeline(), or dispatch()) with a .type derived from untrusted input, an attacker can inject CRLF sequences (\r\n) to append arbitrary HTTP headers and potentially smuggle a second request past the upstream. The vulnerable branch in lib/dispatcher/client-h1.js pushes body.type directly into the outgoing headers with no validation, while every other header path in undici goes through isValidHeaderValue(): The bug requires a hand-rolled duck-typed blob object or a Blob subclass with a controlled .type. Native Blob is safe because its constructor strips CRLF from .type. fetch() is unaffected because it validates via the Headers class. Ecosystem consumers that build duck-typed blob shapes from user input include form-data-encoder, formdata-polyfill, and formdata-node. Same defect class as CVE-2022-35948 (explicit content-type sink, fixed in undici 5.8.2) and…
Recommended action: Upgrade to 8.9.0, 7.29.0 or 6.28.0 by release line, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
Impact Undici's cache interceptor mishandles optional whitespace (OWS) placed around the = of a qualified no-cache or private Cache-Control directive, such as no-cache ="authorization" (OWS before =) or no-cache= "authorization" (OWS after =). The parser either drops the directive entirely or stores a field name with literal quote characters, so the downstream cache decisions do not recognize the qualification and the response is stored. In shared-cache mode, this allows a response containing one user's authenticated data to be served from cache to a subsequent caller, including an unauthenticated caller, when both requests resolve to the same cache key. The impact class is identical to CVE-2026-9678 (GHSA-pr7r-676h-xcf6); this advisory covers the whitespace-around-= bypass that the earlier fix did not normalize. Affected applications are those that explicitly enable the cache interceptor (interceptors.cache()) in shared mode, forward Authorization headers upstream, and receive…
Recommended action: Upgrade to 8.9.0 or 7.29.0 by release line, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
Impact The setCookie function has two attribute injection paths. validateCookieDomain does not reject semicolons (validateCookiePath already does at 0x3B), so a domain value like example.com; SameSite=None lands verbatim as Domain=example.com; SameSite=None. The unparsed array's loop only checks each entry contains = and does not sanitize values, so an entry like X-Custom=val; HttpOnly lands unchanged, injecting HttpOnly without the caller setting cookie.httpOnly = true. Applications that pass user-controlled input to these fields, typically multi-tenant or reverse-proxy servers that scope session cookies to a tenant-supplied domain, can have SameSite CSRF protections bypassed, Secure or HttpOnly forced or stripped, or the intended SameSite tier overridden. Patches Patched in undici v6.28.0, v7.29.0, and v8.9.0. Workarounds - Sanitize domain values against the RFC 1034 letter-digit-hyphen set before passing to setCookie. - Do not pass user-controlled data to the unparsed field.
Recommended action: Upgrade to 8.9.0, 7.29.0 or 6.28.0 by release line, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
Impact Undici's interceptors.retry() can deliver a response whose body length does not match the Content-Length header exposed to the application after a retry or resume of a partial response. Applications that use interceptors.retry() and forward upstream response headers and bodies downstream, for example proxy or gateway applications, may emit an invalid HTTP response with a stale Content-Length header. This can lead to downstream response desynchronization, connection hangs, or response corruption in clients or intermediaries that rely on the forwarded framing metadata. A malicious or faulty upstream can respond to a range request with a 206 Partial Content response such as: and then send only 99 bytes before closing the socket. interceptors.retry() can then retry with Range: bytes=99-99, receive the final byte, and deliver a 100-byte body to the application while the response headers still contain Content-Length: 300 from the first response. The bug requires interceptors.retry()…
Recommended action: Upgrade to 8.9.0, 7.29.0 or 6.28.0 by release line, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.
Two issues in undici's cache interceptor, both fixed by the same patch on lib/util/cache.js: 1. Shared-cache disclosure: Responses with malformed qualified Cache-Control: private directives such as private="" or private="," can be incorrectly stored in the default shared cache, then served to a later caller with the same cache key. 2. Parse-time crash: Mixed unqualified-and-qualified private directives in the same header (such as public, max-age=60, private, private="hdr") cause an uncaught TypeError in the cache-control parser, terminating the request. Impact Shared-cache disclosure Applications using interceptors.cache() in shared mode may cache a user-specific response and serve it to a later caller with the same cache key. This can disclose private response bodies and headers, including Set-Cookie. Required conditions: - the cache interceptor is enabled in shared mode, including the default configuration; - an upstream returns a malformed directive such as Cache-Control:…
Recommended action: Upgrade to 8.9.0 or 7.29.0 by release line, then redeploy and verify.A vendor fix does not resolve your finding until you verify it in your own systems.