CVE-2024-37890
High · 7.5CVSS
7.5
EPSS
1.4%
Published
Jun 17, 2024
CISA due date
—
Cloudanix analysis
A flaw in a commonly used WebSocket component can let an unauthenticated attacker knock affected real-time application services offline with specially crafted connection requests.
- 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
The flaw is a remotely triggerable denial-of-service condition in the Node.js ws WebSocket library. In vulnerable versions, a client can send an HTTP WebSocket upgrade request containing more headers than the configured server.maxHeadersCount threshold, causing the ws server process to crash instead of safely rejecting the request. The vulnerability requires no authentication, no user interaction, and is network-reachable wherever a vulnerable ws-based WebSocket endpoint is exposed. The impact is availability-only: it does not provide confidentiality or integrity access by itself.
Why it matters to the business
Applications that rely on ws for WebSocket services can be taken offline by a small number of crafted requests, disrupting real-time features such as chat, collaboration, notifications, dashboards, device communication, streaming updates, or API gateways. Because exploitation is unauthenticated and low-complexity, internet-facing services are the highest priority even though the issue is not listed in CISA KEV, has no known ransomware association, and currently has low EPSS likelihood. The issue has been public since June 2024, so organizations should assume scanners and opportunistic testing may exist even if mature public exploitation is not currently reported.
How an attack unfolds
An attacker first identifies a Node.js service exposing a WebSocket upgrade endpoint that uses a vulnerable version of the ws package. The attacker then sends a crafted HTTP request that asks to upgrade to WebSocket while including an unusually large number of HTTP headers, specifically enough to exceed the Node.js server.maxHeadersCount setting. Instead of handling the over-limit header condition safely, the vulnerable ws code can trigger an unhandled failure path that terminates the server process or worker. The attacker can repeat the request to keep the service unavailable, especially where process supervisors automatically restart the service but no upstream rate limiting or header normalization is in place. No valid application credentials or successful WebSocket session are required.
How to fix it
Upgrade ws to a fixed release. Use ws 8.17.1 or later for the 8.x line, ws 7.5.10 or later for the 7.x line, ws 6.2.3 or later for the 6.x line, or ws 5.2.4 or later for the 5.x line. If consuming directly from Git, ensure the code includes the upstream fix, including commit aa8fe0a93f65a5aad9e9724d14c09950682c46c4 or the relevant backport. Rebuild and redeploy applications so the updated dependency is actually present in runtime images and lockfiles. Where immediate upgrade is not possible, reduce the maximum allowed request header size using Node.js --max-http-header-size or the maxHeaderSize option so clients cannot send enough headers to cross the maxHeadersCount threshold, or set server.maxHeadersCount to 0 so the vulnerable limit path is not reached. Add reverse-proxy or load-balancer protections to reject WebSocket upgrade requests with abnormal header counts and apply rate limiting to upgrade attempts.
How to confirm the fix worked
Confirm dependency remediation by inspecting package manifests and lockfiles for ws versions 8.17.1+, 7.5.10+, 6.2.3+, or 5.2.4+ depending on the major line in use, and by verifying deployed artifacts or container images contain the same fixed version under node_modules/ws/package.json. Run software composition analysis against built images, not only source repositories. Validate runtime mitigation by checking Node.js startup arguments and HTTP server options for maxHeaderSize or --max-http-header-size, and reviewing server.maxHeadersCount configuration. In a controlled non-production environment, send a WebSocket upgrade request with a header count above the configured limit and confirm the server rejects or closes the request without crashing, restarting, or returning sustained 5xx errors. Monitor process uptime and WebSocket availability after testing.
Typical attack path
- Discover a public or internal WebSocket endpoint, commonly indicated by HTTP 101 upgrade behavior or paths used by real-time application features.
- Fingerprint the service as likely Node.js/ws through headers, behavior, application responses, dependency disclosure, or source/package metadata.
- Send a WebSocket upgrade request containing the required WebSocket headers plus an excessive number of additional HTTP headers exceeding server.maxHeadersCount.
- Trigger a crash or worker termination in the vulnerable ws handling path.
- Repeat the crafted requests to cause sustained denial of service or frequent restarts.
How to detect it
To determine whether exploitation has already occurred, correlate WebSocket access logs, reverse-proxy logs, WAF logs, application logs, process-manager logs, container orchestration events, and host telemetry. Look for HTTP requests containing WebSocket upgrade headers with an unusually high number of total headers, especially followed immediately by Node.js process exits, container restarts, health-check failures, HTTP 5xx spikes, or WebSocket disconnect storms. Useful log sources include NGINX, Apache, Envoy, HAProxy, cloud load balancer logs, CDN/WAF request logs, Node.js application stdout/stderr, PM2/systemd logs, Kubernetes pod events, container runtime logs, and APM traces. Indicators are behavioral rather than payload-specific: repeated Upgrade: websocket requests from the same source, abnormal header counts, low request volume causing high availability impact, and restart loops shortly after upgrade attempts. Because common access logs often do not record every request header or header count, enable enhanced logging or WAF rules for WebSocket upgrade requests when investigating suspected exploitation.
- Upgrade: websocket
- Connection: Upgrade
- Sec-WebSocket-Key:
- Sec-WebSocket-Version: 13
- HTTP/1.1" 101
- HTTP/1.1" 400
- HTTP/1.1" 431
- node_modules/ws/package.json
- "ws": "8.17.0"
- "ws": "7.5.9"
- "ws": "6.2.2"
- "ws": "5.2.3"
- pm2: App [
- exited with code
- Killing container
- Back-off restarting failed container
What your security team should do
- Prioritize inventory of internet-facing Node.js services and APIs that expose WebSocket endpoints using the ws package.
- Upgrade ws to 8.17.1+, 7.5.10+, 6.2.3+, or 5.2.4+ and redeploy all affected applications, containers, serverless bundles, and packaged artifacts.
- Use SCA tooling and lockfile review to identify transitive ws usage, because many frameworks and real-time libraries depend on ws indirectly.
- Add edge controls to reject WebSocket upgrade requests with excessive header counts and rate-limit repeated upgrade attempts from the same source.
- Review application and process-manager logs for unexplained Node.js crashes or restarts correlated with WebSocket upgrade traffic.
- Where upgrades are delayed, apply the documented mitigations using --max-http-header-size, maxHeaderSize, or server.maxHeadersCount configuration and document the risk acceptance period.
- Add regression tests that send oversized-header-count WebSocket upgrade requests and verify graceful rejection instead of process termination.
The record
ws is an open source WebSocket client and server for Node.js. A request with a number of headers exceeding theserver.maxHeadersCount threshold could be used to crash a ws server. The vulnerability was fixed in ws@8.17.1 (e55e510) and backported to ws@7.5.10 (22c2876), ws@6.2.3 (eeb76d3), and ws@5.2.4 (4abd8f6). In vulnerable versions of ws, the issue can be mitigated in the following ways: 1. Reduce the maximum allowed length of the request headers using the --max-http-header-size=size and/or the maxHeaderSize options so that no more headers than the server.maxHeadersCount limit can be sent. 2. Set server.maxHeadersCount to 0 so that no limit is applied.
Affected packages
| Ecosystem | Package | Introduced | Fixed |
|---|---|---|---|
| npm | ws | 2.1.0 | 5.2.4 |
| npm | ws | 6.0.0 | 6.2.3 |
| npm | ws | 7.0.0 | 7.5.10 |
| npm | ws | 8.0.0 | 8.17.1 |
| Chainguard | argo-workflow-cli | 0 | 3.6.5-r2 |
| Chainguard | argo-workflow-controller | 0 | 3.6.5-r2 |
| Chainguard | argo-workflow-controller-compat | 0 | 3.6.5-r2 |
| Chainguard | argo-workflow-executor | 0 | 3.6.5-r2 |
| Chainguard | argo-workflow-executor-compat | 0 | 3.6.5-r2 |
| Chainguard | argo-workflows | 0 | 3.6.5-r2 |
| Chainguard | argo-workflows-known-hosts | 0 | 3.6.5-r2 |
| Chainguard | argo-workflows-ui | 0 | 3.6.5-r2 |
| Chainguard | kibana-7 | 0 | 7.17.24-r0 |
| Chainguard | kibana-7-bitnami | 0 | 7.17.24-r0 |
| Chainguard | kibana-7.17 | 0 | 7.17.29-r0 |
| Chainguard | kibana-8 | 0 | 8.17.3-r2 |
| Chainguard | kibana-8-bitnami | 0 | 8.17.3-r2 |
| Chainguard | kibana-8-iamguarded | 0 | 8.17.3-r2 |
| Chainguard | kubeflow-centraldashboard | 0 | 1.8.0-r5 |
| Chainguard | kubeflow-pipelines | 0 | 2.2.0-r4 |
| Chainguard | kubeflow-pipelines-apiserver | 0 | 2.2.0-r4 |
| Chainguard | kubeflow-pipelines-cache-deployer | 0 | 2.2.0-r4 |
| Chainguard | kubeflow-pipelines-cache-deployer-compat | 0 | 2.2.0-r4 |
| Chainguard | kubeflow-pipelines-cache_server | 0 | 2.2.0-r4 |
| Chainguard | kubeflow-pipelines-frontend | 0 | 2.2.0-r4 |
| Chainguard | kubeflow-pipelines-metadata-envoy-config | 0 | 2.2.0-r4 |
| Chainguard | kubeflow-pipelines-metadata-writer | 0 | 2.2.0-r4 |
| Chainguard | kubeflow-pipelines-metadata-writer-compat | 0 | 2.2.0-r4 |
| Chainguard | kubeflow-pipelines-persistence_agent | 0 | 2.2.0-r4 |
| Chainguard | kubeflow-pipelines-scheduledworkflow | 0 | 2.2.0-r4 |
| Chainguard | kubeflow-pipelines-viewer-crd-controller | 0 | 2.2.0-r4 |
| Chainguard | opensearch-dashboards-2 | 0 | 2.15.0-r1 |
| Chainguard | opensearch-dashboards-2-alerting-dashboards-plugin | 0 | 2.15.0-r1 |
| Chainguard | opensearch-dashboards-2-anomaly-detection-dashboards-plugin | 0 | 2.15.0-r1 |
| Chainguard | opensearch-dashboards-2-compat | 0 | 2.15.0-r1 |
| Chainguard | opensearch-dashboards-2-config | 0 | 2.15.0-r1 |
| Chainguard | opensearch-dashboards-2-dashboards-maps | 0 | 2.15.0-r1 |
| Chainguard | opensearch-dashboards-2-dashboards-notifications | 0 | 2.15.0-r1 |
| Chainguard | opensearch-dashboards-2-dashboards-observability | 0 | 2.15.0-r1 |
| Chainguard | opensearch-dashboards-2-dashboards-query-workbench | 0 | 2.15.0-r1 |
| Chainguard | opensearch-dashboards-2-dashboards-reporting | 0 | 2.15.0-r1 |
| Chainguard | opensearch-dashboards-2-dashboards-search-relevance | 0 | 2.15.0-r1 |
| Chainguard | opensearch-dashboards-2-dashboards-visualizations | 0 | 2.15.0-r1 |
| Chainguard | opensearch-dashboards-2-fips | 0 | 2.15.0-r1 |
| Chainguard | opensearch-dashboards-2-fips-alerting-dashboards-plugin | 0 | 2.15.0-r1 |
| Chainguard | opensearch-dashboards-2-fips-anomaly-detection-dashboards-plugin | 0 | 2.15.0-r1 |
| Chainguard | opensearch-dashboards-2-fips-config | 0 | 2.15.0-r1 |
| Chainguard | opensearch-dashboards-2-fips-dashboards-maps | 0 | 2.15.0-r1 |
| Chainguard | opensearch-dashboards-2-fips-dashboards-notifications | 0 | 2.15.0-r1 |
| Chainguard | opensearch-dashboards-2-fips-dashboards-observability | 0 | 2.15.0-r1 |
| Chainguard | opensearch-dashboards-2-fips-dashboards-query-workbench | 0 | 2.15.0-r1 |
| Chainguard | opensearch-dashboards-2-fips-dashboards-reporting | 0 | 2.15.0-r1 |
| Chainguard | opensearch-dashboards-2-fips-dashboards-search-relevance | 0 | 2.15.0-r1 |
| Chainguard | opensearch-dashboards-2-fips-dashboards-visualizations | 0 | 2.15.0-r1 |
| Chainguard | opensearch-dashboards-2-fips-index-management-dashboards-plugin | 0 | 2.15.0-r1 |
| Chainguard | opensearch-dashboards-2-fips-ml-commons-dashboards | 0 | 2.15.0-r1 |
| Chainguard | opensearch-dashboards-2-fips-security-analytics-dashboards-plugin | 0 | 2.15.0-r1 |
| Chainguard | opensearch-dashboards-2-fips-security-dashboards-plugin | 0 | 2.15.0-r1 |
| Chainguard | opensearch-dashboards-2-index-management-dashboards-plugin | 0 | 2.15.0-r1 |
| Chainguard | opensearch-dashboards-2-ml-commons-dashboards | 0 | 2.15.0-r1 |
| Chainguard | opensearch-dashboards-2-security-analytics-dashboards-plugin | 0 | 2.15.0-r1 |
| Chainguard | opensearch-dashboards-2-security-dashboards-plugin | 0 | 2.15.0-r1 |
| Debian:11 | node-ws | 0 | No fix |
| Debian:12 | node-ws | 0 | No fix |
| Debian:13 | node-ws | 0 | 8.18.0+~cs13.7.11-1 |
| Debian:14 | node-ws | 0 | 8.18.0+~cs13.7.11-1 |
| Mageia:9 | yarnpkg | 0 | 1.22.22-0.10.9.2.1.mga9 |
| Ubuntu:16.04:LTS | node-ws | 0 | No fix |
| Ubuntu:18.04:LTS | node-ws | 0 | No fix |
| Ubuntu:20.04:LTS | node-ws | 0 | No fix |
| Ubuntu:22.04:LTS | node-ws | 0 | No fix |
| Ubuntu:24.04:LTS | node-ws | 0 | No fix |
| Ubuntu:24.10 | node-ws | 0 | No fix |
| Ubuntu:25.04 | node-ws | 0 | No fix |
| Ubuntu:25.10 | node-ws | 0 | No fix |
| Ubuntu:Pro:16.04:LTS | node-ws | 0 | No fix |
| Ubuntu:Pro:18.04:LTS | node-ws | 0 | No fix |
| Ubuntu:Pro:20.04:LTS | node-ws | 0 | No fix |
| Wolfi | argo-workflow-cli | 0 | 3.6.5-r2 |
| Wolfi | argo-workflow-controller | 0 | 3.6.5-r2 |
| Wolfi | argo-workflow-controller-compat | 0 | 3.6.5-r2 |
| Wolfi | argo-workflow-executor | 0 | 3.6.5-r2 |
| Wolfi | argo-workflow-executor-compat | 0 | 3.6.5-r2 |
| Wolfi | argo-workflows | 0 | 3.6.5-r2 |
| Wolfi | argo-workflows-known-hosts | 0 | 3.6.5-r2 |
| Wolfi | argo-workflows-ui | 0 | 3.6.5-r2 |
| Wolfi | kubeflow-centraldashboard | 0 | 1.8.0-r5 |
| Wolfi | kubeflow-pipelines | 0 | 2.2.0-r4 |
| Wolfi | kubeflow-pipelines-apiserver | 0 | 2.2.0-r4 |
| Wolfi | kubeflow-pipelines-cache-deployer | 0 | 2.2.0-r4 |
| Wolfi | kubeflow-pipelines-cache-deployer-compat | 0 | 2.2.0-r4 |
| Wolfi | kubeflow-pipelines-cache_server | 0 | 2.2.0-r4 |
| Wolfi | kubeflow-pipelines-frontend | 0 | 2.2.0-r4 |
| Wolfi | kubeflow-pipelines-metadata-envoy-config | 0 | 2.2.0-r4 |
| Wolfi | kubeflow-pipelines-metadata-writer | 0 | 2.2.0-r4 |
| Wolfi | kubeflow-pipelines-metadata-writer-compat | 0 | 2.2.0-r4 |
| Wolfi | kubeflow-pipelines-persistence_agent | 0 | 2.2.0-r4 |
| Wolfi | kubeflow-pipelines-scheduledworkflow | 0 | 2.2.0-r4 |
| Wolfi | kubeflow-pipelines-viewer-crd-controller | 0 | 2.2.0-r4 |
| Wolfi | opensearch-dashboards-2 | 0 | 2.15.0-r1 |
| Wolfi | opensearch-dashboards-2-alerting-dashboards-plugin | 0 | 2.15.0-r1 |
| Wolfi | opensearch-dashboards-2-anomaly-detection-dashboards-plugin | 0 | 2.15.0-r1 |
| Wolfi | opensearch-dashboards-2-compat | 0 | 2.15.0-r1 |
| Wolfi | opensearch-dashboards-2-config | 0 | 2.15.0-r1 |
| Wolfi | opensearch-dashboards-2-dashboards-maps | 0 | 2.15.0-r1 |
| Wolfi | opensearch-dashboards-2-dashboards-notifications | 0 | 2.15.0-r1 |
| Wolfi | opensearch-dashboards-2-dashboards-observability | 0 | 2.15.0-r1 |
| Wolfi | opensearch-dashboards-2-dashboards-query-workbench | 0 | 2.15.0-r1 |
| Wolfi | opensearch-dashboards-2-dashboards-reporting | 0 | 2.15.0-r1 |
| Wolfi | opensearch-dashboards-2-dashboards-search-relevance | 0 | 2.15.0-r1 |
| Wolfi | opensearch-dashboards-2-dashboards-visualizations | 0 | 2.15.0-r1 |
| Wolfi | opensearch-dashboards-2-index-management-dashboards-plugin | 0 | 2.15.0-r1 |
| Wolfi | opensearch-dashboards-2-ml-commons-dashboards | 0 | 2.15.0-r1 |
| Wolfi | opensearch-dashboards-2-security-analytics-dashboards-plugin | 0 | 2.15.0-r1 |
| Wolfi | opensearch-dashboards-2-security-dashboards-plugin | 0 | 2.15.0-r1 |
Related vulnerabilities
- CVE-2026-48779 ws is an open source WebSocket client and server for Node.js. Also affects ws
- GHSA-96hv-2xvq-fx4p ws: Memory exhaustion DoS from tiny fragments and data chunks Also affects ws
- GHSA-58qx-3vcg-4xpx ws: Uninitialized memory disclosure Also affects ws
- CVE-2026-45736 ws is an open source WebSocket client and server for Node.js. Also affects ws
- GHSA-5v72-xg48-5rpm Denial of Service in ws Also affects ws
- CVE-2025-47907 Cancelling a query (e.g. Also affects argo-workflow-cli
- CVE-2025-7339 on-headers is a node.js middleware for listening to when a response writes headers. Also affects argo-workflow-cli
- CVE-2025-5889 A vulnerability was found in juliangruber brace-expansion up to 1.1.11/2.0.1/3.0.0/4.0.0. Also affects argo-workflow-cli