CVE-2026-2229
High · 7.5CVSS
7.5
EPSS
0.9%
Published
Mar 12, 2026
CISA due date
—
Cloudanix analysis
A malicious WebSocket server can crash affected Node.js applications that connect to it by sending a bad compression setting.
- Exploitation
- Remote Unauthenticated
- Attacker needs
- None
- Complexity
- Low
- Impact
- Denial Of Service
- Component
- Library
- Class
- Denial of service
- Remediation
- Upgrade
- Effort
- Medium
- Patch risk
- Low
What it actually does
CVE-2026-2229 is a network-reachable denial-of-service vulnerability in the undici WebSocket client for Node.js. The client automatically advertises support for the permessage-deflate WebSocket compression extension, but insufficiently validates the server_max_window_bits value returned by a WebSocket server. If a malicious or compromised server returns an out-of-range value outside zlib's valid 8–15 windowBits range and then sends a compressed frame, undici attempts to instantiate zlib InflateRaw with the invalid value. This raises a synchronous RangeError that is not caught, allowing the exception to propagate and terminate the Node.js process. The impact is availability loss of the affected process; there is no direct confidentiality or integrity impact described.
Why it matters to the business
Applications, workers, agents, bots, crawlers, integrations, and backend services that use undici as a WebSocket client can be crashed by connecting to a malicious or compromised WebSocket server. This can cause service interruptions, failed real-time integrations, job failures, degraded customer-facing functionality, or repeated crash loops if the application automatically reconnects. The CVSS score is high for availability impact, but EPSS is currently low and the issue is not listed in CISA KEV, so remediation should be prioritized for systems that initiate WebSocket connections to untrusted, third-party, user-controlled, or internet-reachable endpoints.
How an attack unfolds
An attacker operates or compromises a WebSocket server that an affected Node.js application connects to using undici. During the WebSocket handshake, the undici client advertises permessage-deflate support. The malicious server accepts the extension but returns an invalid server_max_window_bits value, such as a value below 8 or above 15, while still formatted as ASCII digits. Because vulnerable undici validation checks the value format but not the valid zlib range, the handshake can proceed. When the server later sends a compressed WebSocket frame, undici attempts to create a zlib InflateRaw instance using the attacker-supplied invalid windowBits value. Node.js throws a RangeError synchronously, and because the vulnerable code path does not catch it, the exception terminates the process. The attacker can repeat this against reconnecting clients to sustain denial of service.
How to fix it
Upgrade undici to a version that validates server_max_window_bits within zlib's supported range and safely handles decompression initialization errors. No fixed version was provided in the input, so consult the official undici advisory, npm package metadata, Node.js security releases if undici is bundled through the runtime, and lockfile dependency trees to identify the patched release applicable to the deployed version. Rebuild and redeploy applications after updating package manifests and lockfiles. If immediate upgrade is not possible, reduce exposure by disabling WebSocket compression/permessage-deflate where configurable, avoiding connections to untrusted WebSocket servers, enforcing allowlists for outbound WebSocket destinations, and wrapping WebSocket client lifecycle code with process-level error handling and supervised restart limits. Treat process-level exception handlers as a resilience measure, not a complete fix, because the vulnerable parsing behavior remains present.
How to confirm the fix worked
Confirm whether applications include vulnerable undici versions by inspecting package manifests and lockfiles, using software composition analysis, and checking transitive dependencies. Validate runtime exposure by identifying code paths that create WebSocket client connections through undici, especially to third-party or user-supplied URLs. After upgrading, test with a controlled WebSocket server that negotiates permessage-deflate with invalid server_max_window_bits values such as 7 or 16 and sends a compressed frame; a fixed client should reject the negotiation or handle the error without process termination. Confirm that deployed containers, serverless bundles, and packaged artifacts contain the updated dependency, not only the source repository. Monitor restart counts and application error logs after deployment to ensure the RangeError crash condition no longer occurs.
Typical attack path
- Identify or induce a Node.js application using undici to initiate WebSocket connections to an attacker-controlled or compromised server.
- Complete the WebSocket handshake and negotiate the permessage-deflate extension.
- Return an invalid server_max_window_bits value outside the valid zlib range of 8 through 15 while keeping the value syntactically numeric.
- Send a compressed WebSocket frame to trigger decompression setup on the client.
- Cause undici to call zlib InflateRaw with the invalid windowBits value.
- Trigger an uncaught RangeError that terminates the Node.js process.
- Repeat the interaction if the application supervisor, container orchestrator, or process manager automatically restarts the service.
How to detect it
Look for evidence of unexplained Node.js process termination shortly after outbound WebSocket connections, especially connections followed by permessage-deflate negotiation. Relevant sources include application logs, Node.js uncaught exception logs, process manager logs such as systemd, PM2, Docker, Kubernetes, and serverless platform logs, outbound proxy logs, DNS logs, and network captures of WebSocket handshakes. Search for RangeError exceptions involving invalid zlib windowBits, InflateRaw, permessage-deflate, server_max_window_bits, and WebSocket compressed frames. In network telemetry or packet captures, inspect HTTP Upgrade responses from WebSocket servers for Sec-WebSocket-Extensions headers containing permessage-deflate with server_max_window_bits values outside 8–15, such as 0, 7, 16, 32, 999, or other numeric values. Correlate crashes or restart events with outbound connections to the same WebSocket host, unusual destinations, recently changed partner endpoints, or endpoints controlled by users. There are no public KEV or named threat actor associations in the provided data, so detection should focus on behavioral crash indicators and malicious WebSocket negotiation artifacts rather than actor-specific infrastructure.
- RangeError
- ERR_OUT_OF_RANGE
- The value of "windowBits" is out of range
- InflateRaw
- createInflateRaw
- server_max_window_bits=0
- server_max_window_bits=1
- server_max_window_bits=7
- server_max_window_bits=16
- server_max_window_bits=32
- server_max_window_bits=999
- Sec-WebSocket-Extensions: permessage-deflate; server_max_window_bits=7
- Sec-WebSocket-Extensions: permessage-deflate; server_max_window_bits=16
- permessage-deflate; server_max_window_bits=7
- permessage-deflate; server_max_window_bits=16
- uncaughtException
- Unhandled 'error' event
- WebSocket
- permessage-deflate
What your security team should do
- Inventory Node.js services, workers, and automation that use undici for outbound WebSocket client connections.
- Prioritize remediation for services connecting to external, partner, user-controlled, dynamically configured, or otherwise untrusted WebSocket endpoints.
- Upgrade undici or the Node.js runtime/package bundle once the applicable patched version is identified from official advisories, and redeploy all packaged artifacts that include the dependency.
- Disable permessage-deflate/WebSocket compression for affected clients where feasible until patched.
- Restrict outbound WebSocket connections with egress allowlists, DNS controls, or proxy policy so clients cannot connect to arbitrary malicious servers.
- Add regression testing with malicious permessage-deflate parameters to verify the process does not crash.
- Monitor Node.js process crashes, container restarts, supervisor restarts, and uncaught RangeError exceptions related to zlib windowBits or InflateRaw.
- Review dependency lockfiles and transitive dependency usage to ensure all applications using undici receive the fix, including bundled or vendored copies.
The record
ImpactThe undici WebSocket client is vulnerable to a denial-of-service attack due to improper validation of the server_max_window_bits parameter in the permessage-deflate extension. When a WebSocket client connects to a server, it automatically advertises support for permessage-deflate compression. A malicious server can respond with an out-of-range server_max_window_bits value (outside zlib's valid range of 8-15). When the server subsequently sends a compressed frame, the client attempts to create a zlib InflateRaw instance with the invalid windowBits value, causing a synchronous RangeError exception that is not caught, resulting in immediate process termination. The vulnerability exists because: * The isValidClientWindowBits() function only validates that the value contains ASCII digits, not that it falls within the valid range 8-15 * The createInflateRaw() call is not wrapped in a try-catch block * The resulting exception propagates up through the call stack and crashes the Node.js process
Affected packages
| Ecosystem | Package | Introduced | Fixed |
|---|---|---|---|
| npm | undici | 0 | 6.24.0 |
| npm | undici | 7.0.0 | 7.24.0 |
| Chainguard | code-server | 0 | 4.110.1-r2 |
| Chainguard | jitsucom-jitsu-console | 0 | 2.11.0-r17 |
| Chainguard | jitsucom-jitsu-rotor | 0 | 2.11.0-r17 |
| Chainguard | kibana-8.17 | 0 | 8.17.10-r13 |
| Chainguard | kibana-8.17-bitnami | 0 | 8.17.10-r13 |
| Chainguard | kibana-8.17-iamguarded | 0 | 8.17.10-r13 |
| Chainguard | kibana-8.18-bitnami | 0 | 8.18.8-r11 |
| Chainguard | kibana-8.19 | 0 | 8.19.13-r4 |
| Chainguard | kibana-8.19-bitnami | 0 | 8.19.13-r4 |
| Chainguard | kibana-8.19-iamguarded | 0 | 8.19.13-r4 |
| Chainguard | kibana-9.0 | 0 | 9.0.8-r14 |
| Chainguard | kibana-9.0-bitnami | 0 | 9.0.8-r14 |
| Chainguard | kibana-9.0-iamguarded | 0 | 9.0.8-r14 |
| Chainguard | kibana-9.1 | 0 | 9.1.10-r7 |
| Chainguard | kibana-9.1-iamguarded | 0 | 9.1.10-r7 |
| Chainguard | kibana-9.2 | 0 | 9.2.7-r0 |
| Chainguard | kibana-9.2-iamguarded | 0 | 9.2.6-r3 |
| Chainguard | kibana-9.3 | 0 | 9.3.2-r0 |
| Chainguard | kibana-9.3-iamguarded | 0 | 9.3.2-r0 |
| Chainguard | pelias-api | 0 | 7.6.0-r4 |
| Chainguard | renovate | 0 | 43.84.0-r1 |
| Wolfi | code-server | 0 | 4.110.1-r2 |
| Wolfi | jitsucom-jitsu-console | 0 | 2.11.0-r17 |
| Wolfi | jitsucom-jitsu-rotor | 0 | 2.11.0-r17 |
| Wolfi | renovate | 0 | 43.84.0-r1 |
Related vulnerabilities
- GHSA-v9p9-hfj2-hcw8 Undici has Unhandled Exception in WebSocket Client Due to Invalid server_max_window_bits… 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