You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
chore(deps): update dependency undici@>=7.0.0 <7.29.1 to v7.30.1 [security] - #350
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.
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 backpressure and resume on drain, bounding the outbound queue.
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 valid certificates, the first matching the requested URL and the second intentionally not matching it.
Patches
Upgrade to undici 6.29.1, 7.30.1, or 8.12.2.
Workarounds
Restrict outbound connections to TLS 1.3, for example by setting connect: { minVersion: 'TLSv1.3', maxVersion: 'TLSv1.3' } on the client or agent, so that renegotiation cannot occur, when the target endpoints support TLS 1.3.
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 connect is not affected. This is the Agent counterpart of the BalancedPool certificate validation bypass fixed in CVE-2026-84961.
Patches
Upgrade to undici 6.29.1, 7.30.1, or 8.12.2. Agent now preserves the tls option outside the JSON clone, so custom TLS verification callbacks are forwarded to each origin unchanged.
Workarounds
Pass the TLS options through connect instead of tls. For proxied EnvHttpProxyAgent destinations, use requestTls / proxyTls.
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 all 7.x and 8.x releases before the patched versions are affected. Applications are affected only when an originless Agent, a shared MemoryCacheStore or SqliteCacheStore, and the composition compose(redirect(), cache()) are all used. Origin-bound Client and Pool dispatchers, and the reverse composition compose(cache(), redirect()), are not affected.
Patches
Upgrade to 7.30.1 or 8.12.2. Before storing a response, undici now verifies that the origin that produced it still matches the cache key, and preserves each redirect hop's cache-control policy, so cross-origin redirect responses and responses behind a no-store or private hop are no longer cached under the original key.
Workarounds
Compose the interceptors as compose(cache(), redirect()), use per-origin dispatchers and cache stores, or disable shared caching on redirect-capable requests.
A malicious or compromised HTTPS server could crash the Node.js process by initiating TLS 1.2 renegotiation and presenting a different, CA-trusted certificate whose hostname did not match the requested host. The resulting socket error reached an assertion in undici's HTTP/1.1 and HTTP/2 connection handling. This release handles post-connect certificate errors without terminating the process.
TLS certificate validation bypass through dropped Agent options
Agent used a JSON-based clone for constructor options, which silently removed function-valued TLS options such as checkServerIdentity. Applications relying on custom certificate or public-key verification could therefore accept a certificate that the callback was intended to reject. This release preserves TLS options when creating per-origin dispatchers.
Cache poisoning and cross-user disclosure through cross-origin redirects
When an originless Agent combined redirect and shared-cache interceptors as compose(redirect(), cache()), a response from a cross-origin redirect could be stored under the original URL. This could allow persistent cache poisoning or disclosure of user-specific responses to later callers. This release verifies the response origin before caching and preserves redirect-hop cache-control policy.
Denial of service through excessive Content-Encoding values
A malicious HTTP server could crash the Node.js process by returning more than five content codings and closing the connection before sending the body. Although fetch() rejected the response, an error from an orphaned internal stream could remain unhandled. This release validates the content-encoding chain before creating the body stream and aborts oversized chains safely.
Medium severity
Denial of service through the decompress interceptor
An exception thrown by a downstream response handler from an asynchronous decompression callback could escape as an uncaught exception. A server could trigger this when decompress was composed with a handler such as dump with a size limit. This release converts downstream handler exceptions into per-request errors.
Subresource Integrity bypass with non-lowercase algorithm tokens
fetch() treated valid mixed-case or uppercase SRI algorithm tokens, such as SHA256, as unknown and could accept a response whose body did not match the configured digest. This release normalizes algorithm tokens before validation and digest selection.
Denial of service through unbounded EventSource parser state
A malicious Server-Sent Events endpoint could exhaust process memory by sending many tiny data: fields without completing an event, or by splitting an unfinished line across many chunks. This release bounds retained EventSource parser state, including field counts, buffered chunks, unfinished-line length, and retained field data.
Denial of service through unbounded automatic WebSocket PONG buffering
A malicious WebSocket server could exhaust process memory by flooding the client with PING frames while not reading the automatic PONG responses. undici previously ignored socket backpressure and allowed the outbound queue to grow without bound. This release pauses frame parsing when PONG writes encounter backpressure and resumes after the socket drains.
What's Changed
test: disable timeouts in h2 high concurrency regression by @mcollina in #5893
test: reduce retry-after invalid date timing flake by @mcollina in #5892
Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.
This PR includes no changesets
When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types
System calls cannot be simulated consistently and are left out of the measure. The reported value understates the real cost. Switch to the Walltime instrument to measure them.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This PR contains the following updates:
7.29.1→7.30.1](https://renovatebot.com/diffs/npm/undici@>=7.0.0 <7.29.1/7.29.1/7.30.1)Warning
Some dependencies could not be looked up. Check the Dependency Dashboard for more information.
undici vulnerable to Denial of Service via unhandled error on excessive content-encodings
CVE-2026-109869 / GHSA-xjj6-f33q-929c
More information
Details
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 unhandlederrorand terminates the process. A remote, unauthenticated server can trigger this with a single response, even when the application correctly catches thefetch()rejection. undici 6.x, 7.x, and 8.x are affected.Patches
Upgrade to
6.29.1,7.30.1, or8.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.
Severity
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:HReferences
This data is provided by the GitHub Advisory Database (CC-BY 4.0).
undici WebSocket client vulnerable to Denial of Service via unbounded automatic PONG buffering
CVE-2026-109932 / GHSA-9fm3-97px-rjf6
More information
Details
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 thefalsereturn value fromsocket.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, or8.12.2, which pause WebSocket frame parsing when the automatic PONG response hits socket backpressure and resume on drain, bounding the outbound queue.Workarounds
None.
Severity
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:N/A:HReferences
This data is provided by the GitHub Advisory Database (CC-BY 4.0).
undici vulnerable to Denial of Service via TLS 1.2 certificate-changing renegotiation
CVE-2026-87018 / GHSA-qrxm-fqhp-jwvm
More information
Details
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 uncaughtAssertionErrorthat 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 valid certificates, the first matching the requested URL and the second intentionally not matching it.Patches
Upgrade to undici 6.29.1, 7.30.1, or 8.12.2.
Workarounds
Restrict outbound connections to TLS 1.3, for example by setting
connect: { minVersion: 'TLSv1.3', maxVersion: 'TLSv1.3' }on the client or agent, so that renegotiation cannot occur, when the target endpoints support TLS 1.3.Severity
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:HReferences
This data is provided by the GitHub Advisory Database (CC-BY 4.0).
undici vulnerable to TLS certificate validation bypass via dropped tls options in Agent
CVE-2026-109383 / GHSA-2m5v-pch6-74hx
More information
Details
Impact
undici's
Agentpasses its constructor options through a JSON-based deep clone (JSON.parse(JSON.stringify(...))) before forwarding them to each per-originPool. JSON cannot represent functions, so a caller-suppliedtlsoption containing acheckServerIdentitycallback is silently dropped before it reaches the TLS layer. As a result, a TLS peer whose certificate a customcheckServerIdentitywas written to reject, but which passes Node's default hostname and chain checks, is silently accepted when the request is made throughAgent. BecauseAgentis the default dispatcher behindrequest,fetch, andsetGlobalDispatcher, this is the path most applications use.EnvHttpProxyAgentis also affected on its direct andNO_PROXYroutes, which delegate to an internalAgent.Only applications that pass a function-valued
tlsoption (such as a customcheckServerIdentityfor certificate or public-key pinning) are affected. Passing the same options throughconnectis not affected. This is theAgentcounterpart of theBalancedPoolcertificate validation bypass fixed in CVE-2026-84961.Patches
Upgrade to undici
6.29.1,7.30.1, or8.12.2.Agentnow preserves thetlsoption outside the JSON clone, so custom TLS verification callbacks are forwarded to each origin unchanged.Workarounds
Pass the TLS options through
connectinstead oftls. For proxiedEnvHttpProxyAgentdestinations, userequestTls/proxyTls.Severity
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:NReferences
This data is provided by the GitHub Advisory Database (CC-BY 4.0).
undici vulnerable to cache poisoning and cross-user disclosure via cross-origin redirects
CVE-2026-109829 / GHSA-4w7w-5xrc-9h26
More information
Details
Impact
When an originless
Agentcomposes the redirect and cache interceptors ascompose(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-storeredirect 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 all 7.x and 8.x releases before the patched versions are affected. Applications are affected only when an originless
Agent, a sharedMemoryCacheStoreorSqliteCacheStore, and the compositioncompose(redirect(), cache())are all used. Origin-boundClientandPooldispatchers, and the reverse compositioncompose(cache(), redirect()), are not affected.Patches
Upgrade to
7.30.1or8.12.2. Before storing a response, undici now verifies that the origin that produced it still matches the cache key, and preserves each redirect hop's cache-control policy, so cross-origin redirect responses and responses behind ano-storeorprivatehop are no longer cached under the original key.Workarounds
Compose the interceptors as
compose(cache(), redirect()), use per-origin dispatchers and cache stores, or disable shared caching on redirect-capable requests.Severity
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:NReferences
This data is provided by the GitHub Advisory Database (CC-BY 4.0).
Release Notes
nodejs/undici (undici@>=7.0.0 <7.29.1)
v7.30.1Compare Source
Security fixes
High severity
Denial of service via TLS 1.2 certificate-changing renegotiation
CVE-2026-87018 · GHSA-qrxm-fqhp-jwvm
A malicious or compromised HTTPS server could crash the Node.js process by initiating TLS 1.2 renegotiation and presenting a different, CA-trusted certificate whose hostname did not match the requested host. The resulting socket error reached an assertion in undici's HTTP/1.1 and HTTP/2 connection handling. This release handles post-connect certificate errors without terminating the process.
TLS certificate validation bypass through dropped
AgentoptionsCVE-2026-109383 · GHSA-2m5v-pch6-74hx
Agentused a JSON-based clone for constructor options, which silently removed function-valued TLS options such ascheckServerIdentity. Applications relying on custom certificate or public-key verification could therefore accept a certificate that the callback was intended to reject. This release preserves TLS options when creating per-origin dispatchers.Cache poisoning and cross-user disclosure through cross-origin redirects
CVE-2026-109829 · GHSA-4w7w-5xrc-9h26
When an originless
Agentcombined redirect and shared-cache interceptors ascompose(redirect(), cache()), a response from a cross-origin redirect could be stored under the original URL. This could allow persistent cache poisoning or disclosure of user-specific responses to later callers. This release verifies the response origin before caching and preserves redirect-hop cache-control policy.Denial of service through excessive
Content-EncodingvaluesCVE-2026-109869 · GHSA-xjj6-f33q-929c
A malicious HTTP server could crash the Node.js process by returning more than five content codings and closing the connection before sending the body. Although
fetch()rejected the response, an error from an orphaned internal stream could remain unhandled. This release validates the content-encoding chain before creating the body stream and aborts oversized chains safely.Medium severity
Denial of service through the
decompressinterceptorCVE-2026-87029 · GHSA-55wc-3pg8-jfw6
An exception thrown by a downstream response handler from an asynchronous decompression callback could escape as an uncaught exception. A server could trigger this when
decompresswas composed with a handler such asdumpwith a size limit. This release converts downstream handler exceptions into per-request errors.Subresource Integrity bypass with non-lowercase algorithm tokens
CVE-2026-109841 · GHSA-f72v-6w45-q472
fetch()treated valid mixed-case or uppercase SRI algorithm tokens, such asSHA256, as unknown and could accept a response whose body did not match the configured digest. This release normalizes algorithm tokens before validation and digest selection.Denial of service through unbounded EventSource parser state
CVE-2026-109924 · GHSA-4qv8-2p9j-2685
A malicious Server-Sent Events endpoint could exhaust process memory by sending many tiny
data:fields without completing an event, or by splitting an unfinished line across many chunks. This release bounds retained EventSource parser state, including field counts, buffered chunks, unfinished-line length, and retained field data.Denial of service through unbounded automatic WebSocket PONG buffering
CVE-2026-109932 · GHSA-9fm3-97px-rjf6
A malicious WebSocket server could exhaust process memory by flooding the client with PING frames while not reading the automatic PONG responses. undici previously ignored socket backpressure and allowed the outbound queue to grow without bound. This release pauses frame parsing when PONG writes encounter backpressure and resumes after the socket drains.
What's Changed
New Contributors
Full Changelog: nodejs/undici@v7.30.0...v7.30.1
v7.30.0Compare Source
What's Changed
Full Changelog: nodejs/undici@v7.29.1...v7.30.0
Configuration
📅 Schedule: (UTC)
🚦 Automerge: Enabled.
♻ Rebasing: Whenever PR is behind base branch, or you tick the rebase/retry checkbox.
🔕 Ignore: Close this PR and you won't be reminded about this update again.
This PR was generated by Mend Renovate. View the repository job log.