Skip to main content
Vulnerability Database/CVE-2026-84961

CVE-2026-84961: undici BalancedPool Privilege Escalation

CVE-2026-84961 is a privilege escalation flaw in undici's BalancedPool that silently discards TLS security callbacks, allowing unauthorized certificate acceptance. This article covers technical details, affected versions, and mitigation.

Published:

CVE-2026-84961 Overview

CVE-2026-84961 affects the undici HTTP client library for Node.js. The BalancedPool constructor passes its entire options object through an internal deep-clone that serializes and reparses the value as JSON. Because JSON cannot represent functions, any function-valued TLS option is silently discarded before it reaches the TLS layer. This includes caller-supplied checkServerIdentity callbacks and custom connector functions inside the connect option. Applications relying on these callbacks to reject specific peer certificates lose that protection when routing through BalancedPool. The vulnerability is classified under [CWE-295: Improper Certificate Validation].

Critical Impact

A peer whose certificate the application's custom checkServerIdentity was written to reject, but which still passes Node's default hostname and chain checks, is accepted when reached through BalancedPool.

Affected Products

  • undici versions 7.24.1 through 7.29.0
  • undici versions 8.0.0 through 8.10.1
  • Node.js applications using BalancedPool with function-valued connect or tls options

Discovery Timeline

  • 2026-09-04 - CVE-2026-84961 published to NVD
  • 2026-09-08 - Last updated in NVD database

Technical Details for CVE-2026-84961

Vulnerability Analysis

The flaw resides in the BalancedPool dispatcher within undici. During construction, BalancedPool performs a deep-clone of the caller-supplied options object using JSON.stringify followed by JSON.parse. This serialization step cannot represent JavaScript function values. Any function property on the options object is silently stripped during the round-trip.

When an application supplies a custom checkServerIdentity callback within the tls option, or a custom connect function, those callbacks never reach the underlying TLS layer. Node.js falls back to default hostname and certificate chain validation. Any peer whose certificate passes the default checks is accepted, even if the custom callback would have rejected it.

The Client, Pool, and Agent dispatchers are not affected because they extract the connect and tls options before performing the clone. Only BalancedPool exhibits this behavior. Exploitation requires the application to depend on a function-valued TLS option for pinning or additional identity verification.

Root Cause

The root cause is the use of JSON-based serialization for deep-cloning a configuration object that legitimately contains function values. JSON is a data-only format and drops function properties without warning. The BalancedPool constructor did not exclude function-valued fields from cloning as the sibling dispatchers do.

Attack Vector

An attacker who controls a rogue upstream server, or who can intercept traffic to a legitimate upstream, can present a certificate that passes Node's default validation but would have been rejected by the application's custom callback. Because the callback is discarded, the connection succeeds. This enables man-in-the-middle interception, credential capture, or response tampering against applications that used custom identity verification as a security control. Exploitation requires network positioning and a certificate that satisfies default chain validation.

No verified public proof-of-concept code is available. See the GitHub Security Advisory GHSA-w293-vg96-wgc3 for technical details.

Detection Methods for CVE-2026-84961

Indicators of Compromise

  • TLS connections established to upstream hosts whose certificates would have been rejected by the application's checkServerIdentity callback.
  • Application logs showing successful BalancedPool requests to endpoints that should have failed custom certificate pinning checks.
  • Absence of expected callback-generated log entries from checkServerIdentity or custom connect functions when using BalancedPool.

Detection Strategies

  • Audit application dependency trees for undici versions between 7.24.1 and 7.29.0 or between 8.0.0 and 8.10.1 using npm ls undici or equivalent.
  • Statically scan source code for new BalancedPool(...) invocations that pass tls or connect options containing function values.
  • Add runtime assertions inside custom checkServerIdentity callbacks to log every invocation, then verify these logs fire for BalancedPool traffic.

Monitoring Recommendations

  • Capture TLS handshake metadata for outbound traffic originating from Node.js services and alert on unexpected certificate issuers or subject alternative names.
  • Monitor package registries and software bill of materials (SBOM) feeds for vulnerable undici versions in production builds.
  • Correlate outbound TLS destinations with an allowlist of expected upstream fingerprints to detect certificate substitution.

How to Mitigate CVE-2026-84961

Immediate Actions Required

  • Upgrade undici to version 7.29.1 or 8.10.2 immediately in all affected services.
  • Inventory application code for direct or transitive use of BalancedPool with function-valued tls or connect options.
  • Rotate any credentials or tokens that may have been transmitted over connections established through vulnerable BalancedPool instances.

Patch Information

The maintainers fixed the issue in undici 7.29.1 and 8.10.2. The patched versions extract function-valued connect and tls options before the internal deep-clone, matching the behavior of the Client, Pool, and Agent dispatchers. Refer to the GitHub Security Advisory GHSA-w293-vg96-wgc3 and the OpenJS Foundation Security Advisories for release notes.

Workarounds

  • Replace BalancedPool with Pool, Client, or Agent dispatchers, which are not affected by this flaw.
  • Move custom certificate validation logic out of the tls option and enforce it after connection establishment using the peer certificate returned by the socket.
  • Pin upstream identities using non-function TLS options such as ca, cert, and servername where possible until the upgrade is deployed.
bash
# Upgrade undici to a patched release
npm install undici@7.29.1
# or, for the 8.x line
npm install undici@8.10.2

# Verify the installed version
npm ls undici

Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

Experience the Most Advanced Cybersecurity Platform

See how the world’s most intelligent, autonomous cybersecurity platform can protect your organization today and into the future.