CVE-2026-22036
Low · 3.7Undici has an unbounded decompression chain in HTTP responses on Node.js Fetch API via Content-Encoding leads to resource exhaustion
CVSS
3.7
EPSS
0.5%
Published
Jan 14, 2026
CISA due date
—
Cloudanix analysis
A malicious website can make affected Node.js applications that fetch it waste large amounts of computing resources and potentially stop responding.
- Exploitation
- Requires User Interaction
- Attacker needs
- None
- Complexity
- Moderate
- Impact
- Denial Of Service
- Component
- Library
- Class
- Denial of service
- Remediation
- Upgrade
- Effort
- Medium
- Patch risk
- Low
What it actually does
This is a denial-of-service flaw in Node.js undici's fetch()/decompression handling. When an HTTP response contains a Content-Encoding header with a very long chain of compression algorithms, such as thousands of gzip or br entries, undici attempts to process the chain without a practical upper bound. A malicious server can therefore cause the client process to spend excessive CPU time and allocate excessive memory while decoding the response, potentially slowing, hanging, or crashing the Node.js process that initiated the request. The issue affects applications that use the affected undici implementation directly or indirectly through fetch-like HTTP client behavior and that retrieve content from attacker-controlled or untrusted HTTP endpoints.
Why it matters to the business
The main risk is service degradation or outage in applications that fetch content from untrusted or user-influenced URLs. An attacker does not need to compromise the application; they only need to cause it to request a malicious HTTP response. This can disrupt background jobs, API workers, SSRF-prone services, webhook processors, URL previewers, crawlers, proxying services, or integrations that retrieve third-party content. The CVSS score and EPSS are low, it is not listed in CISA KEV, and no mature public exploitation is indicated, but organizations with high-volume Node.js services or URL-fetching features should still remediate because the exploit condition is simple once an attacker can influence a fetched URL.
How an attack unfolds
An attacker operates or compromises an HTTP server and configures it to return a response with an extremely long Content-Encoding chain, for example many repeated gzip, br, or deflate values, while also returning response content that triggers decompression handling. The attacker then causes a vulnerable Node.js application using undici fetch() to request that URL. This may be achieved through a user-submitted URL, webhook destination, import feature, crawler target, metadata fetcher, server-side rendering path, proxy endpoint, or any integration that fetches remote content. When the vulnerable client receives the response, undici parses the header and attempts to apply each declared decompression layer. Because the chain length is not bounded, the client consumes excessive CPU and memory. Repeated requests can amplify the effect, exhausting process resources, increasing latency, causing worker restarts, or producing an application-level outage.
How to fix it
Upgrade undici to a version that includes the upstream fix. For source-based or Git-pinned deployments, update nodejs/undici to commit fbc31e21d7e1dffea61166ab7a827f74b6483d26 or a later commit/release containing that fix. Also update any Node.js runtime or dependency bundle that vendors undici if the application relies on built-in fetch() behavior. As defense in depth, restrict server-side fetching to trusted destinations where possible, enforce allowlists for outbound fetch targets, set aggressive request and response timeouts, cap maximum response size, limit redirects, isolate URL-fetching workers, and monitor/enforce CPU and memory limits so a single malicious response cannot exhaust shared service capacity.
How to confirm the fix worked
Confirm dependency resolution shows a patched undici version or a Git revision at or after fbc31e21d7e1dffea61166ab7a827f74b6483d26. Review package-lock.json, npm-shrinkwrap.json, pnpm-lock.yaml, yarn.lock, container SBOMs, and built artifacts for vulnerable undici copies, including transitive dependencies. If relying on Node.js built-in fetch(), verify the deployed Node.js build includes the patched undici implementation. In a controlled non-production test, configure a local HTTP server to return a response with a long repeated Content-Encoding chain and confirm the patched application rejects, limits, or safely handles the response without sustained CPU spikes, memory growth, event-loop stalls, or process termination. Validate that operational controls such as timeouts, memory limits, and outbound URL allowlists are active.
Typical attack path
- Identify a Node.js application feature that fetches remote HTTP or HTTPS content using undici or a fetch() implementation backed by undici.
- Host or control an HTTP endpoint that returns a response with an extremely long Content-Encoding header chain, such as many repeated gzip or br encodings.
- Cause the vulnerable application to request the malicious endpoint through a URL submission, webhook, integration, crawler, proxy, or similar server-side fetch path.
- The application receives the response and undici attempts to process the unbounded decompression chain.
- The Node.js process experiences high CPU usage, excessive memory allocation, event-loop delay, request timeouts, worker crashes, or container/pod restarts.
- Repeat requests or parallelize delivery to sustain denial of service.
How to detect it
To determine whether this was already exploited, focus on services that perform outbound HTTP requests using Node.js, undici, or fetch(). Review application logs, HTTP client debug logs, egress proxy logs, service mesh telemetry, WAF/proxy response-header captures, APM traces, and container/runtime metrics. Look for outbound requests followed by responses containing unusually long Content-Encoding headers, especially repeated gzip, br, or deflate values. Correlate those requests with spikes in CPU, memory growth, garbage-collection pressure, event-loop delay, request timeout errors, process out-of-memory events, worker restarts, container OOMKilled events, or autoscaling events. Because the malicious payload is in the HTTP response from a server the application contacted, inbound web logs may only show the trigger request that supplied or selected the URL; the most useful evidence is outbound egress logging and response-header capture. If response headers were not logged historically, look for timing correlation between user-submitted URLs or webhook targets and resource exhaustion in the fetching service.
- Content-Encoding: gzip, gzip, gzip, gzip
- Content-Encoding: br, br, br, br
- Content-Encoding: deflate, deflate, deflate, deflate
- Content-Encoding: gzip, br, gzip, br
- Content-Encoding: br, gzip, br, gzip
- UND_ERR_HEADERS_OVERFLOW
- JavaScript heap out of memory
- FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed
- FATAL ERROR: Reached heap limit Allocation failed
- ENOMEM
- OOMKilled
- Event loop delay
- fetch failed
- TypeError: fetch failed
- HeadersTimeoutError
- BodyTimeoutError
What your security team should do
- Inventory Node.js services that use undici directly or use fetch() to retrieve remote content, especially services accepting user-provided URLs or processing webhooks and third-party integrations.
- Upgrade nodejs/undici to a release or Git revision containing fbc31e21d7e1dffea61166ab7a827f74b6483d26, and update Node.js runtime images if they vendor the affected implementation.
- Prioritize internet-facing or externally influenced URL-fetching services before internal-only batch jobs, because attacker-controlled responses are the key exploit condition.
- Add outbound fetch guardrails: destination allowlists, redirect limits, request timeouts, response-size limits, connection limits, and workload isolation for URL retrieval components.
- Search logs and telemetry for prior responses with abnormally long Content-Encoding headers and correlate with CPU spikes, memory pressure, event-loop lag, request timeouts, or process restarts.
- Add regression tests that exercise malformed or excessive Content-Encoding chains to prevent future reintroduction of unbounded decompression behavior.
The record
The `fetch()` API supports chained HTTP encoding algorithms for response content according to RFC 9110 (e.g., Content-Encoding: gzip, br). This is also supported by the undici decompress interceptor. However, the number of links in the decompression chain is unbounded and the default maxHeaderSize allows a malicious server to insert thousands compression steps leading to high CPU usage and excessive memory allocation.
Affected packages
| Ecosystem | Package | Introduced | Fixed |
|---|---|---|---|
| npm | undici | 0 | 6.23.0 |
| npm | undici | 7.0.0 | 7.18.2 |
| Chainguard | code-server | 0 | 4.106.3-r2 |
| Chainguard | jitsucom-jitsu-console | 0 | 2.11.0-r12 |
| Chainguard | jitsucom-jitsu-rotor | 0 | 2.11.0-r12 |
| Chainguard | kibana-8.19 | 0 | 8.19.10-r2 |
| Chainguard | kibana-8.19-bitnami | 0 | 8.19.10-r2 |
| Chainguard | kibana-8.19-iamguarded | 0 | 8.19.10-r2 |
| Chainguard | kibana-9.0 | 0 | 9.0.8-r7 |
| Chainguard | kibana-9.0-bitnami | 0 | 9.0.8-r7 |
| Chainguard | kibana-9.0-iamguarded | 0 | 9.0.8-r7 |
| Chainguard | kibana-9.1 | 0 | 9.1.10-r2 |
| Chainguard | kibana-9.1-iamguarded | 0 | 9.1.10-r2 |
| Chainguard | kibana-9.2 | 0 | 9.2.3-r4 |
| Chainguard | kibana-9.2-iamguarded | 0 | 9.2.3-r4 |
| Chainguard | langfuse-3-worker | 0 | 3.146.0-r2 |
| Chainguard | langfuse-fips-3-worker | 0 | 3.147.0-r1 |
| Chainguard | librechat | 0 | 0.8.1-r5 |
| Chainguard | renovate | 0 | 42.94.1-r2 |
| SUSE:Linux Enterprise Server 15 SP6-LTSS | nodejs20 | 0 | 20.20.0-150600.3.15.1 |
| SUSE:Linux Enterprise Server 15 SP6-LTSS | nodejs22 | 0 | 22.22.0-150600.13.12.1 |
| SUSE:Linux Enterprise Server for SAP Applications 15 SP6 | nodejs20 | 0 | 20.20.0-150600.3.15.1 |
| SUSE:Linux Enterprise Server for SAP Applications 15 SP6 | nodejs22 | 0 | 22.22.0-150600.13.12.1 |
| Wolfi | code-server | 0 | 4.106.3-r2 |
| Wolfi | jitsucom-jitsu-console | 0 | 2.11.0-r12 |
| Wolfi | jitsucom-jitsu-rotor | 0 | 2.11.0-r12 |
| Wolfi | langfuse-3-worker | 0 | 3.146.0-r2 |
| Wolfi | renovate | 0 | 42.94.1-r2 |
| openSUSE:Leap 15.6 | nodejs20 | 0 | 20.20.0-150600.3.15.1 |
| openSUSE:Leap 15.6 | nodejs22 | 0 | 22.22.0-150600.13.12.1 |
| openSUSE:Leap 16.0 | nodejs22 | 0 | 22.22.0-160000.1.1 |
| openSUSE:Tumbleweed | nodejs22 | 0 | 22.22.0-1.1 |
| openSUSE:Tumbleweed | nodejs24 | 0 | 24.13.0-2.1 |
| openSUSE:Tumbleweed | nodejs26 | 0 | 26.3.1-1.1 |
Related vulnerabilities
- GHSA-g9mf-h72j-4rw9 Undici has an unbounded decompression chain in HTTP responses on Node.js Fetch API via… Same vulnerability
- GHSA-g8m3-5g58-fq7m undici vulnerable to Set-Cookie SameSite attribute downgrade via permissive substring… Also affects undici
- GHSA-vxpw-j846-p89q undici WebSocket client vulnerable to denial of service via fragment count bypass Also affects undici
- GHSA-p88m-4jfj-68fv undici vulnerable to HTTP header injection via Set-Cookie percent-decoding Also affects undici
- GHSA-hm92-r4w5-c3mj undici vulnerable to cross-origin request routing via SOCKS5 proxy pool reuse Also affects undici
- GHSA-35p6-xmwp-9g52 undici vulnerable to HTTP response queue poisoning via keep-alive socket reuse Also affects undici
- GHSA-vmh5-mc38-953g undici vulnerable to TLS certificate validation bypass via dropped requestTls in SOCKS5… Also affects undici
- GHSA-pr7r-676h-xcf6 undici vulnerable to cross-user information disclosure via shared cache whitespace bypass Also affects undici