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

CVE-2026-18149: undici Retry Handler DOS Vulnerability

CVE-2026-18149 is a denial of service vulnerability in undici that causes pending response bodies to hang indefinitely. Attackers can exhaust resources through repeated requests. This article covers technical details, affected versions, and mitigation.

Published:

CVE-2026-18149 Overview

CVE-2026-18149 is a resource exhaustion vulnerability [CWE-772] in undici, the HTTP/1.1 client used by Node.js. The retry handler can orphan an already-exposed response body when a server sends a truncated response followed by a non-retryable status on retry. Applications reading the original body wait indefinitely because the body timeout is bound to the connection parser rather than the orphaned stream. Repeated abuse accumulates pending promises and streams, degrading availability. The flaw affects undici versions 7.11.0 through 7.29.1 and 8.0.0 through 8.10.2.

Critical Impact

An attacker-controlled server can exhaust application concurrency or memory by triggering unresolvable response promises with two short HTTP responses per request.

Affected Products

  • undici versions 7.11.0 up to 7.29.1
  • undici versions 8.0.0 up to 8.10.2
  • Node.js applications and libraries embedding vulnerable undici releases as an HTTP client

Discovery Timeline

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

Technical Details for CVE-2026-18149

Vulnerability Analysis

The defect lives in undici's retry handler path. When an upstream server returns a successful status with a declared Content-Length, transmits only part of the body, and closes the connection, undici triggers a retry. If the retried request returns a non-retryable status such as 400, the handler forwards the new response downstream and replaces its internal response stream. The original response body reference, already handed to the calling application, is never ended or destroyed. Any consumer awaiting .text(), .json(), or a stream end event on that body waits forever. Because the configured body timeout is tied to the connection parser rather than the orphaned stream, no timeout ever fires to unblock the caller. Categorized as a Missing Release of Resource after Effective Lifetime, the issue converts a hostile HTTP interaction into a persistent denial-of-service condition against Node.js services that fetch attacker-influenced URLs.

Root Cause

The retry handler swaps its internal response stream when a retry produces a non-retryable status, but it does not signal end-of-stream or destroy the body reference already returned to the caller. The body timeout logic is scoped to the parser on the underlying socket, so once the parser advances to the retried response, the orphaned body has no watchdog.

Attack Vector

An attacker who controls or influences a URL fetched by a Node.js application serves two responses per victim request. The first advertises Content-Length larger than the bytes sent, then closes the connection. The second returns any non-retryable status such as 400. Each interaction leaks a pending promise and stream reference. Repeated requests exhaust concurrency limits, event loop resources, or heap memory. No open connection or authentication is required, though the attack requires the ability to steer a target's HTTP client toward the malicious endpoint.

See the GitHub Security Advisory GHSA-pmjh-fq2x-6v4x for the maintainer's technical write-up.

Detection Methods for CVE-2026-18149

Indicators of Compromise

  • Growing counts of unresolved promises or open ReadableStream handles in Node.js process telemetry without corresponding completed HTTP transactions.
  • Repeated short-lived HTTP/1.1 responses from a single upstream that declare a Content-Length larger than the bytes actually sent before the peer closes the socket.
  • Rising heap size, event loop lag, or worker saturation correlated with outbound requests to a specific host.

Detection Strategies

  • Inventory Node.js services for undici versions in the vulnerable ranges using npm ls undici or software bill of materials tooling.
  • Instrument outbound HTTP clients to log responses where received body bytes are less than the advertised Content-Length and the connection closed early.
  • Alert when the ratio of in-flight fetch operations to completed operations grows monotonically over time in a single process.

Monitoring Recommendations

  • Track Node.js process metrics such as activeHandles, activeRequests, resident set size, and event loop delay in application performance monitoring.
  • Log and rate-limit outbound requests to untrusted or user-supplied hostnames and inspect for repeated truncated responses.
  • Forward outbound HTTP client telemetry and Node.js runtime metrics into a centralized analytics platform to correlate resource growth with upstream behavior.

How to Mitigate CVE-2026-18149

Immediate Actions Required

  • Upgrade undici to 7.29.1 or 8.10.2 across all Node.js applications, container images, and Lambda-style runtimes.
  • Rebuild and redeploy any transitive dependents that bundle undici, including frameworks that ship their own HTTP client.
  • Restart long-running Node.js processes after upgrade to release any already-orphaned body handles.

Patch Information

The undici maintainers fixed the issue in versions 7.29.1 and 8.10.2. Refer to the GitHub Security Advisory GHSA-pmjh-fq2x-6v4x and the OpenJS Foundation Security Advisories for release notes and commit references.

Workarounds

  • Wrap outbound fetch or undici request calls with an application-level timeout using AbortController so orphaned body reads terminate deterministically.
  • Restrict outbound HTTP destinations to an allowlist of trusted hosts to reduce exposure to attacker-controlled servers.
  • Apply concurrency caps and circuit breakers on outbound HTTP paths so a single misbehaving upstream cannot exhaust process resources.
bash
# Upgrade undici to a fixed release
npm install undici@8.10.2
# or, for the 7.x line
npm install undici@7.29.1

# Verify no vulnerable versions remain in the dependency tree
npm ls undici

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

Default Legacy - Prefooter | Experience the World’s Most Advanced Cybersecurity Platform

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.