Skip to content

Security: nodejs/undici

SECURITY.md

Security

Reporting a vulnerability in undici

Report security bugs in undici via GitHub Security Advisories or HackerOne.

Your report will normally be acknowledged within 5 days, and you will receive a more detailed response within 10 days indicating the next steps in handling your submission. These timelines may extend when our triage volunteers are away, particularly at the end of the year.

After the initial reply to your report, the security team will endeavor to keep you informed of the progress being made towards a fix and full announcement, and may ask for additional information or guidance surrounding the reported issue.

Disclosure policy

  • The security report is received and assigned a primary handler. The problem is validated against all supported versions of undici. Once confirmed, a list of all affected versions is determined. Code is audited to find any potential similar problems. Fixes are prepared for all supported releases. These fixes are not committed to the public repository but rather held locally pending the announcement.

  • Because undici is bundled into Node.js, security releases are often coordinated with the Node.js project to avoid leaving Node.js users vulnerable. As a result, fixed versions of undici are published to npm before the corresponding CVE is disclosed, since the CVE will only be published after the coordinated Node.js release. This delay is typically a few days but can take up to a week.

The undici threat model

Undici is an HTTP client library for Node.js. Its threat model is derived from and aligned with the Node.js threat model. The Node.js policy is authoritative for the copy of undici bundled with Node.js. This section applies the same boundaries to the standalone undici package.

Security triage dispositions

Security reports are classified using the same dispositions as Node.js:

  • Vulnerability: An undici defect that is exploitable across an undici-owned security boundary and meets the criteria under What constitutes a vulnerability, including any applicable DoS criteria.
  • Security-interest bug: A real undici defect, or an API behavior likely to cause security bugs in applications, that is not itself a vulnerability under this threat model. These are fixed as regular bugs and do not automatically receive a CVE, but should still be reported privately first when they affect a common security control such as protocol interpretation, certificate validation, or TLS decisions.
  • Common bug: A correctness, robustness, or crash issue without an undici-owned security boundary or a realistic cross-boundary attacker benefit.
  • Invalid / out of scope: A report that cannot be reproduced, is not an undici defect, or concerns behavior excluded by this policy.

What constitutes a vulnerability

Being able to cause the following through control of the elements that undici does not trust is considered a vulnerability:

  • Disclosure or loss of integrity or confidentiality of data protected through the correct use of undici APIs.
  • The unavailability of the runtime, including the unbounded degradation of its performance.

Denial of Service (DoS) vulnerabilities

For a behavior to be considered a DoS vulnerability, the proof of concept must meet the following criteria:

  • The API is being correctly used.
  • The API does not have a warning against its use in production.
  • The API is public and documented. For standards-based APIs, the behavior must be well-defined by the applicable specification.
  • The API is stable. For APIs bundled in Node.js, it must have stable (2.0) status.
  • The behavior is significant enough to cause a denial of service quickly or in a context not controlled by the application developer, such as protocol parsing.
  • The behavior is directly exploitable by an untrusted source without requiring application mistakes.
  • The behavior cannot be reasonably mitigated through standard operational practices, such as process recycling.
  • The behavior occurs deterministically under normal usage patterns rather than only in edge cases.
  • The behavior occurs at a rate that would cause practical resource exhaustion within a practical timeframe under typical workloads.
  • The attack demonstrates asymmetric resource consumption, where the attacker expends significantly fewer resources than the client must expend to process the attack. Attacks requiring comparable resources on the attacker's side, which can be mitigated through practices such as rate limiting, may not qualify.

Undici does NOT trust:

  • Data received from the remote end of outbound network connections created through undici APIs and transformed or validated by undici before being passed to the application, except with respect to payload length. Undici trusts applications to make connections and requests that avoid payload sizes that would result in a denial of service. Subject to that exception, untrusted data includes:
    • HTTP response headers and status lines.
    • HTTP response bodies processed by undici, such as chunked transfer decoding and content-encoding.
    • WebSocket frames received from a server.
    • Server-Sent Events (EventSource) data received from a server.
  • TLS certificate validation performed by undici on behalf of the application.

Undici trusts:

  • The application code that uses its APIs, including all configuration, options, callbacks, connection and request decisions, and decisions about which body-consuming APIs to call.
  • The operating system and its network stack.
  • The Node.js runtime undici is running on.
  • Dependencies installed by the application.
  • The DNS resolution results provided by the operating system or configured resolvers.
  • The network environment in which the process runs, including any private or internal networks it can reach, for the privacy of traffic on that network. Deployments that require stronger isolation, monitoring, or egress controls are responsible for providing them.
  • Any proxy server configured by the application, runtime, or environment. Proxies are trusted network intermediaries and must be authorized by the relevant network or deployment authority. Undici's proxy support is for routing traffic through such proxies, for example to reach external networks through a firewall; it is not intended to provide anonymity, hide traffic, or bypass organizational, regulatory, or legal controls. Untrusted proxies are outside the supported threat model.

In other words, if untrusted data passing through undici to the application can trigger actions other than those documented for the APIs, there is likely a security vulnerability. Examples include polluting globals, causing an unrecoverable crash, or other unexpected side effects that can lead to a loss of confidentiality, integrity, or availability.

Examples of vulnerabilities

Improper Certificate Validation (CWE-295)

  • Undici provides TLS connections to HTTPS endpoints. If certificates can be crafted that result in incorrect validation by undici, that is considered a vulnerability.

Inconsistent Interpretation of HTTP Responses (CWE-444)

  • Undici parses HTTP responses received from servers. Bugs in parsing response headers or transfer encoding which can result in response smuggling or desynchronization are considered vulnerabilities.

HTTP Request Smuggling (CWE-444)

  • Bugs that allow crafting requests that are interpreted differently by undici and an upstream server, leading to request smuggling, are considered vulnerabilities.

CRLF Injection in Request Headers (CWE-93)

  • If untrusted input passed to undici APIs, such as header values or URLs, can inject additional headers or corrupt the HTTP request stream, that is considered a vulnerability.

Examples of non-vulnerabilities

Defense-in-depth issues

  • Bugs whose fixes only improve resilience after another security boundary has already failed, or reduce the impact of behavior outside this threat model, are defense-in-depth issues. They are fixed as regular bugs and do not receive CVEs.

Malicious Third-Party Modules (CWE-1357)

  • Application code and its dependencies are trusted by undici. Any scenario that requires a malicious third-party module cannot result in a vulnerability in undici.

Prototype Pollution Attacks (CWE-1321)

  • Undici trusts inputs provided by application code. The application must sanitize them appropriately. A scenario that requires control over user input passed directly by the application is not a vulnerability in undici.

Uncontrolled Resource Consumption on Outbound Connections (CWE-400)

  • If undici is asked to connect to a remote site and return an artifact, it is not a vulnerability if the size of that artifact is large enough to impact performance or cause the runtime to run out of resources. Applications are responsible for choosing suitable response-processing APIs and enforcing limits appropriate for their workloads.

Calling body-consuming methods on untrusted responses

  • The body.arrayBuffer(), body.blob(), body.bytes(), body.formData(), body.json(), and body.text() methods buffer the entire response body in memory before returning. Where applicable, they also decode or parse the payload and retain that representation in memory. Calling one of these methods means the application trusts that the response is small enough to fit in the available memory. Applications must not use these methods on responses from untrusted or user-controlled servers. They should instead process the response with a streaming API, such as Response.body, body.textStream(), or the Readable body returned by undici.request(), and enforce application-specific size limits while streaming. Resource exhaustion caused by buffering an untrusted response is considered an application responsibility, not a vulnerability in undici.

  • Multipart parsing has additional inherent security risks. Applications processing untrusted multipart responses should use a dedicated streaming multipart parser and enforce application-specific limits. Parser exposure caused by calling body.formData() on an untrusted response is considered an application responsibility, not a vulnerability in undici.

HTTP/1.1 keep-alive with untrusted servers

  • HTTP/1.1 responses on a reused connection are ordered, but they do not carry a request identifier. Once a request has been written on a reused connection, a well-formed response sent by the server is the response to that next request from the client's point of view. Undici avoids immediate reuse of non-pipelined HTTP/1.1 connections when callers are already waiting to send more work, but applications that require per-request connection isolation for untrusted or user-controlled servers should disable reuse by using pipelining: 0 or maxRequestsPerClient: 1, or use a protocol with response correlation such as HTTP/2.

Application Misconfiguration

  • Issues arising from incorrect or insecure use of undici APIs, such as disabling TLS verification, ignoring errors, or passing unsanitized user input to request options, are the application's responsibility and not vulnerabilities in undici.

Unauthorized or untrusted proxy use

  • If an application configures undici to use a proxy that is untrusted, malicious, or not authorized by the relevant network or deployment authority, any resulting privacy loss, policy bypass, regulatory exposure, traffic manipulation, or unavailability is the deployment's responsibility. Undici cannot determine whether a proxy is authorized for a user's network or jurisdiction, and preventing use of proxies to hide traffic or evade controls is a non-goal.

Receiving security updates

Security notifications will be distributed via GitHub Security Advisories.

Comments on this policy

If you have suggestions on how this process could be improved, please open an issue on the nodejs/undici repository or file a pull request.

Learn more about advisories related to nodejs/undici in the GitHub Advisory Database