Summary
A flaw in undici can silently discard a caller-provided TLS certificate verification callback when Agent options are copied between per-origin connection pools. Applications that rely on custom certificate or public-key checks may therefore accept a TLS peer that passes Node.js's default validation but should have been rejected by the application.
A flaw in undici can silently discard a caller-provided TLS certificate verification callback when Agent options are copied between per-origin connection pools. Applications that rely on custom certificate or public-key checks may therefore accept a TLS peer that passes Node.js's default validation but should have been rejected by the application.
Affected context
The issue affects undici applications that pass function-valued TLS options, such as a custom checkServerIdentity callback, through the tls option of an Agent. It is relevant to common request paths using the default Agent dispatcher, including request, fetch, and setGlobalDispatcher, and may also affect applicable EnvHttpProxyAgent routes. Applications relying only on Node.js's default hostname and certificate-chain checks are generally outside this specific condition.
The issue affects undici applications that pass function-valued TLS options, such as a custom checkServerIdentity callback, through the tls option of an Agent. It is relevant to common request paths using the default Agent dispatcher, including request, fetch, and setGlobalDispatcher, and may also affect applicable EnvHttpProxyAgent routes. Applications relying only on Node.js's default hostname and certificate-chain checks are generally outside this specific condition.
Exploit preconditions
- Attack surface: Outbound HTTPS connections created through undici's Agent-based dispatcher
- Required access: No special application account is necessarily required; the target application must make a connection to an attacker-controlled or improperly trusted TLS endpoint
- Trigger point: Agent construction and propagation of TLS options to per-origin connection pools
- Required configuration: A function-valued TLS verification option, such as a custom
checkServerIdentity, must be supplied through the affected option path - Why exploitation is possible: JSON-based deep cloning cannot preserve functions, causing the custom verification callback to be omitted before TLS connection establishment
- Attack surface: Outbound HTTPS connections created through undici's Agent-based dispatcher
- Required access: No special application account is necessarily required; the target application must make a connection to an attacker-controlled or improperly trusted TLS endpoint
- Trigger point: Agent construction and propagation of TLS options to per-origin connection pools
- Required configuration: A function-valued TLS verification option, such as a custom
checkServerIdentity, must be supplied through the affected option path - Why exploitation is possible: JSON-based deep cloning cannot preserve functions, causing the custom verification callback to be omitted before TLS connection establishment
Why this happens
The underlying bug is an unsafe configuration-copying pattern. Undici serializes Agent constructor options through a JSON-based deep clone, even though TLS configuration may contain executable callback functions. Because JSON serialization drops functions, a custom certificate or public-key verification callback is silently removed before the options reach Node.js's TLS layer. This maps to CWE-295: Improper Certificate Validation, because a security-relevant certificate validation policy is not applied as intended.
The underlying bug is an unsafe configuration-copying pattern. Undici serializes Agent constructor options through a JSON-based deep clone, even though TLS configuration may contain executable callback functions. Because JSON serialization drops functions, a custom certificate or public-key verification callback is silently removed before the options reach Node.js's TLS layer. This maps to CWE-295: Improper Certificate Validation, because a security-relevant certificate validation policy is not applied as intended.
Potential impact
- A certificate that custom application policy would reject may be accepted
- Public-key or certificate pinning controls may be bypassed
- An attacker could impersonate an HTTPS service under suitable network conditions
- Sensitive outbound requests or response data could be exposed
- Application trust boundaries based on custom TLS verification may be weakened
- A certificate that custom application policy would reject may be accepted
- Public-key or certificate pinning controls may be bypassed
- An attacker could impersonate an HTTPS service under suitable network conditions
- Sensitive outbound requests or response data could be exposed
- Application trust boundaries based on custom TLS verification may be weakened
General mitigation guidance
Mitigation focuses on preserving security-sensitive TLS options throughout connection setup and avoiding serialization mechanisms that cannot represent callbacks.
Common defensive patterns include:
- Use a supported connection configuration path that forwards custom TLS options without JSON serialization
- Keep certificate, hostname, and public-key verification callbacks attached to the TLS connection configuration
- Prefer secure-by-default TLS validation and treat custom verification as an explicitly tested security control
- Verify that proxy and direct-connection routes apply the intended TLS policy independently
- Minimize trust in external endpoints and use least-privilege credentials for outbound services
- Add regression tests that confirm rejected certificates remain rejected through every dispatcher and proxy path
Mitigation focuses on preserving security-sensitive TLS options throughout connection setup and avoiding serialization mechanisms that cannot represent callbacks.
Common defensive patterns include:
- Use a supported connection configuration path that forwards custom TLS options without JSON serialization
- Keep certificate, hostname, and public-key verification callbacks attached to the TLS connection configuration
- Prefer secure-by-default TLS validation and treat custom verification as an explicitly tested security control
- Verify that proxy and direct-connection routes apply the intended TLS policy independently
- Minimize trust in external endpoints and use least-privilege credentials for outbound services
- Add regression tests that confirm rejected certificates remain rejected through every dispatcher and proxy path
How teams detect issues like this
Detection can include:
- Static analysis for JSON serialization or cloning of objects containing TLS callbacks
- Code review checks for
tlsoptions carryingcheckServerIdentityor other function-valued verification settings - Tests using certificates that pass default validation but fail the application's custom policy
- Runtime assertions or telemetry confirming that custom verification callbacks are invoked
- Policy checks requiring security-sensitive TLS options to use supported, non-serializing configuration paths
- Automated dependency and security review tools that flag vulnerable HTTP client library behavior
Detection can include:
- Static analysis for JSON serialization or cloning of objects containing TLS callbacks
- Code review checks for
tlsoptions carryingcheckServerIdentityor other function-valued verification settings - Tests using certificates that pass default validation but fail the application's custom policy
- Runtime assertions or telemetry confirming that custom verification callbacks are invoked
- Policy checks requiring security-sensitive TLS options to use supported, non-serializing configuration paths
- Automated dependency and security review tools that flag vulnerable HTTP client library behavior
Sources
| Source | Link |
|---|---|
| cna. | cna.openjsf.org/ |
| github. | github.com/ |

