Back to Blog
critical SEVERITY7 min read

How WebSocket Header Parsing Vulnerabilities Happen in Node.js and How to Fix Them

CVE-2026-54466 is a critical vulnerability in the `websocket-driver` npm package (versions prior to 0.7.5) that exposes applications to exploitation through malformed WebSocket protocol input. The fix pins the dependency to `0.7.5` via a pnpm override, closing the attack surface in both `faye-websocket` and any other consumers in the dependency tree. Because WebSocket connections are a common real-time communication channel, leaving this unpatched puts any application that handles untrusted WebS

O
By Orbis AppSec
Published August 26, 2026Reviewed August 26, 2026

Answer Summary

CVE-2026-54466 is a critical vulnerability (CWE-20, Improper Input Validation) in the `websocket-driver` npm package ≤0.7.4, which mishandles malformed HTTP upgrade headers during WebSocket handshake parsing. Attackers can send crafted WebSocket handshake requests to trigger the flaw. The fix is to upgrade `websocket-driver` to 0.7.5, enforced via a pnpm `overrides` entry in `package.json` and a corresponding lockfile update in `pnpm-lock.yaml` so all consumers in the dependency tree receive the patched version.

Vulnerability at a Glance

cweCWE-20
fixPin websocket-driver to 0.7.5 via pnpm overrides in package.json and pnpm-lock.yaml
riskRemote attackers can send crafted WebSocket upgrade requests to exploit the vulnerable parser, potentially causing crashes or arbitrary behavior
languageJavaScript / Node.js
root causewebsocket-driver 0.7.4 fails to properly validate untrusted input during WebSocket protocol negotiation
vulnerabilityImproper Input Validation in WebSocket Handshake Parsing

The Hidden Risk in Your WebSocket Dependency Tree

Real-time web applications depend heavily on WebSocket connections — live dashboards, collaborative editors, hot-module replacement in development servers, and more. The libraries powering these connections are often several layers deep in your node_modules tree, far from the code you write every day. That invisibility is exactly what makes transitive dependency vulnerabilities so dangerous.

CVE-2026-54466 is a critical vulnerability discovered in websocket-driver, a foundational WebSocket protocol handler used across the Node.js ecosystem. Version 0.7.4 and earlier contain a flaw in how the library processes WebSocket handshake input. Because websocket-driver is rarely a direct dependency — it typically arrives via faye-websocket, which itself is pulled in by tools like webpack-dev-server — most developers would never notice it sitting in their lockfile, quietly waiting to be exploited.

This post walks through exactly what the vulnerability is, how it was confirmed in a real project's dependency tree, and the precise changes made to close the attack surface.


The Vulnerability Explained

What websocket-driver Does

websocket-driver is a low-level WebSocket protocol handler. Its job is to parse the HTTP Upgrade request that initiates a WebSocket connection, negotiate protocol extensions, and manage the framing of WebSocket messages. Because it sits at the boundary between raw HTTP and the WebSocket protocol, it processes untrusted, attacker-controlled input by design.

What Goes Wrong in 0.7.4

CVE-2026-54466 is rooted in CWE-20: Improper Input Validation. The 0.7.4 release of websocket-driver does not sufficiently validate the structure of incoming WebSocket handshake headers before processing them. An attacker who can send a crafted HTTP Upgrade request to any endpoint backed by this library can trigger the vulnerable code path.

The vulnerable package version is clearly visible in the lockfile before the fix:

# pnpm-lock.yaml (before fix)
websocket-driver@0.7.4:
  resolution: {integrity: sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==}
  engines: {node: '>=0.8.0'}

And it appears in two separate places in the dependency snapshot — once as a direct resolution and twice as a transitive dependency consumed by faye-websocket and webpack-dev-server:

# Snapshot entries (before fix)
faye-websocket@0.11.4:
  dependencies:
    websocket-driver: 0.7.4   # ← vulnerable

# ...

webpack-dev-server@...:
  dependencies:
    faye-websocket: 0.11.4
    uuid: 8.3.2
    websocket-driver: 0.7.4   # ← vulnerable again

This dual appearance is significant: even if you tried to patch one consumer, the other would still pull in the vulnerable version without an explicit override.

Attack Scenario

Consider a development environment running webpack-dev-server for hot-module replacement. The dev server opens a WebSocket endpoint so the browser can receive live reload notifications. An attacker on the same network — or a malicious web page exploiting the dev server's lack of origin enforcement — could send a specially crafted WebSocket Upgrade request with malformed header content. Because websocket-driver 0.7.4 does not properly validate this input before parsing, the crafted request reaches the vulnerable code path inside the protocol handler.

Depending on the exact nature of the flaw, this can result in:
- Denial of service — crashing the dev server process
- Memory corruption or unexpected state — depending on the runtime behavior of the parser
- Protocol confusion — forcing the server into an unexpected WebSocket state that downstream logic is not prepared to handle

While the scanner assessment notes the vulnerability is "present in dependency tree, not confirmed reachable" in production, development tooling is not immune to attack — and the same faye-websocket package is used in production WebSocket servers as well.


The Fix

Pinning the Safe Version via pnpm Overrides

The fix is precise and surgical: it adds a pnpm override that forces the entire dependency tree to resolve websocket-driver to 0.7.5, regardless of what individual packages request.

package.json — before:

"pnpm": {
  "overrides": {
    "fast-xml-parser": "4.5.4",
    "shell-quote": "1.8.4"
  }
}

package.json — after:

"pnpm": {
  "overrides": {
    "fast-xml-parser": "4.5.4",
    "shell-quote": "1.8.4",
    "websocket-driver": "0.7.5"
  }
}

This single line addition is the key control. The overrides field in pnpm tells the package manager: no matter who asks for websocket-driver, give them 0.7.5. This is the correct approach when a vulnerability exists in a transitive dependency you do not control directly.

Lockfile Updates

The pnpm-lock.yaml changes reflect the override taking effect across every location where websocket-driver appeared:

# pnpm-lock.yaml — resolution block (after fix)
websocket-driver@0.7.5:
  resolution: {integrity: sha512-ZL2+3c7kMBdIRCMz6l8jQMHyGVxj+UL+xVk74Ombiciboca8rHa15L86B19E5oh1pL9Ii/uj54gtsIrZGMo6zA==}
  engines: {node: '>=0.8.0'}
# Snapshot entries (after fix)
faye-websocket@0.11.4:
  dependencies:
    websocket-driver: 0.7.5   # ✅ patched

webpack-dev-server@...:
  dependencies:
    faye-websocket: 0.11.4
    uuid: 8.3.2
    websocket-driver: 0.7.5   # ✅ patched

Notice that the integrity hash also changes — from sha512-b17K... to sha512-ZL2+... — confirming that a genuinely different package artifact is being installed. Committing the updated lockfile ensures that every developer and every CI/CD pipeline gets the exact same patched version, with no room for version drift.

Why Two Files Must Change

Updating only package.json would declare the intent to override, but without regenerating pnpm-lock.yaml, the old lockfile would continue to resolve websocket-driver@0.7.4. Both files must be committed together to make the fix deterministic and reproducible across all environments.


Prevention & Best Practices

1. Use Lockfiles and Commit Them

Always commit pnpm-lock.yaml, package-lock.json, or yarn.lock. Lockfiles are the source of truth for what actually gets installed. Without them, npm install or pnpm install can silently resolve to a vulnerable version.

2. Leverage Package Manager Overrides for Transitive Vulnerabilities

When a vulnerability exists in a package you don't depend on directly, use your package manager's override mechanism:

  • pnpm: "pnpm": { "overrides": { "package-name": "safe-version" } } in package.json
  • npm: "overrides": { "package-name": "safe-version" } in package.json (npm 8.3+)
  • yarn: "resolutions": { "package-name": "safe-version" } in package.json

3. Run SCA Scanners in CI

Tools like Trivy, Snyk, and npm audit can detect known-vulnerable packages in your lockfile — including transitive dependencies — before they reach production. Trivy was the scanner that flagged this exact issue via rule CVE-2026-54466.

# Run Trivy against your project
trivy fs --scanners vuln .

# Run npm audit
npm audit

# Run pnpm audit
pnpm audit

4. Subscribe to Security Advisories

Monitor the GitHub Advisory Database and npm security advisories for packages in your dependency tree. Tools like Dependabot and Renovate can automate this.

5. Apply the Principle of Least Exposure

For development-only tools like webpack-dev-server, ensure they are not accessible from untrusted networks. Bind dev servers to localhost only and never expose them on public interfaces.

Relevant standards:
- OWASP A06:2021 – Vulnerable and Outdated Components
- CWE-20: Improper Input Validation


Key Takeaways

  • websocket-driver 0.7.4 is vulnerable; 0.7.5 is the minimum safe version. Any project with faye-websocket or webpack-dev-server in its dependency tree is potentially exposed without the override.
  • Transitive dependencies in pnpm-lock.yaml are part of your attack surface. The vulnerable package appeared in two separate snapshot entries — faye-websocket@0.11.4 and the webpack-dev-server snapshot — requiring both to be updated.
  • A pnpm overrides entry is the correct fix for transitive dependency vulnerabilities. Upgrading a direct dependency is not sufficient when the vulnerable package is two or more levels deep.
  • Lockfile integrity hashes change when the package changes. The shift from sha512-b17K... to sha512-ZL2+... confirms a real artifact change, not just a version label update.
  • Development tooling vulnerabilities are real vulnerabilities. webpack-dev-server is a common attack surface in developer environments; don't treat dev dependencies as low-risk.

How Orbis AppSec Detected This

  • Source: Untrusted input enters via inbound WebSocket Upgrade HTTP requests processed by websocket-driver
  • Sink: The WebSocket handshake parser inside websocket-driver@0.7.4, consumed transitively through faye-websocket@0.11.4 as declared in pnpm-lock.yaml
  • Missing control: Insufficient validation of malformed WebSocket protocol headers before parsing, present in versions ≤0.7.4 and patched in 0.7.5
  • CWE: CWE-20 — Improper Input Validation
  • Fix: Added "websocket-driver": "0.7.5" to the pnpm.overrides block in package.json and regenerated pnpm-lock.yaml to enforce the patched version across all consumers in the dependency tree

Orbis AppSec automatically detected this vulnerability and opened a pull request with the fix. Try Orbis AppSec on your repositories to find and fix issues like this automatically.


Conclusion

CVE-2026-54466 is a reminder that your application's security posture is only as strong as the weakest link in your entire dependency tree — including packages you've never heard of. websocket-driver is not a package most developers think about, yet it processes raw, attacker-controlled network input in millions of Node.js applications every day.

The fix here is minimal in terms of lines changed — two files, one new line in each — but it closes a critical attack surface across every consumer of websocket-driver in the project. The pattern of using pnpm overrides (or npm/yarn equivalents) to enforce safe versions of transitive dependencies is one every Node.js developer should have in their toolkit.

Keep your lockfiles committed, run SCA scanners in CI, and don't let invisible dependencies become invisible risks.


References

Frequently Asked Questions

What is CVE-2026-54466?

CVE-2026-54466 is a critical vulnerability in the websocket-driver npm package (≤0.7.4) that stems from improper validation of WebSocket handshake headers, allowing attackers to send malformed input that exploits the protocol parser.

How do you prevent WebSocket parsing vulnerabilities in Node.js?

Keep WebSocket library dependencies up to date, use pnpm/npm overrides to enforce minimum safe versions across your entire dependency tree, and monitor your lockfile for transitive dependency exposure.

What CWE is this WebSocket vulnerability?

This vulnerability maps to CWE-20 (Improper Input Validation), where the library fails to adequately validate the structure of incoming WebSocket protocol data before processing it.

Is upgrading the direct dependency enough to prevent CVE-2026-54466?

Not always. Because websocket-driver is often a transitive dependency (pulled in by faye-websocket, which is used by tools like webpack-dev-server), you must use package manager overrides to ensure all consumers receive the patched version.

Can static analysis detect this WebSocket vulnerability?

Yes. Trivy and similar software composition analysis (SCA) scanners can detect known-vulnerable versions of websocket-driver in your lockfile, even when it is a transitive dependency several levels deep.

View the Security Fix

Check out the pull request that fixed this vulnerability

View PR #1001

Related Articles

high

How Dependabot Missing Cooldown happens in GitHub Actions and how to fix it

A high-severity misconfiguration in `.github/dependabot.yml` left this Node.js library without a cooldown period, meaning Dependabot would immediately propose updates to newly published packages — including potentially malicious or unstable ones. The fix adds a `cooldown` block with `default-days: 7` to both the `npm` and `github-actions` package ecosystem entries, introducing a mandatory 7-day waiting period before any new package version is surfaced as an update candidate.

critical

How CSRF Protection Failures Happen in FastAPI and How to Fix Them

A critical CORS misconfiguration in `backend/main.py` allowed cookies to be sent alongside wildcard-origin requests, violating the CORS specification and opening the door to cross-site request forgery attacks. The fix conditionally disables `allow_credentials` when the allowed origins list contains a wildcard, bringing the configuration into compliance with browser security rules. This change closes a subtle but dangerous gap that could have let attackers on sibling subdomains forge authenticate

critical

How Missing Rate Limiting Happens in Node.js SSE Handlers and How to Fix It

A critical missing rate-limiting control in `src/sse/handlers/chat.js` allowed any caller to flood the SSE chat endpoint with unlimited requests, risking server resource exhaustion, denial of service, and runaway AI provider API costs. The fix introduces a per-IP sliding-window rate limiter that caps requests at 60 per minute and returns HTTP 429 on violations. Because the endpoint was publicly reachable and only validated API keys — not request frequency — exploitation required nothing more tha

medium

How Denial of Service via Catastrophic Backtracking happens in Node.js and how to fix it

CVE-2026-4867 is a Denial of Service vulnerability in path-to-regexp 0.1.12 where malformed URL parameters can trigger catastrophic backtracking in the library's regular expression engine, allowing an attacker to hang or crash a Node.js application with a single crafted request. The fix upgrades path-to-regexp to version 0.1.13, which patches the vulnerable regex patterns. This change was applied via a package-level override to ensure the patched version is used throughout the entire dependency

high

How Denial of Service via Exponential-Time Complexity happens in Node.js and how to fix it

CVE-2026-13149 is a high-severity Denial of Service vulnerability in the `brace-expansion` npm package, where crafted input strings trigger exponential-time processing that can freeze or crash a Node.js application. The fix upgrades `brace-expansion` from `2.0.2` to `2.1.4` and `minimatch` from `5.1.6` to `5.1.9`, along with npm `overrides` to ensure the patched versions are used throughout the entire dependency tree.

critical

How Unrestricted File Upload happens in Node.js/Express and how to fix it

A critical unrestricted file upload vulnerability was discovered in `mainsystem/routes/admin/profile.js`, where the avatar upload endpoint accepted any file type without validation. An authenticated attacker could upload a malicious server-side script to a web-accessible directory and execute arbitrary code on the server. The fix adds MIME type filtering, an allowlist of safe image formats, and a 2 MB file size limit to the multer middleware.