Back to Blog
critical SEVERITY7 min read

How Unsandboxed Plugin Execution Happens in Node.js and How to Fix It

A critical vulnerability (CVE-2026-54466) was discovered in the `websocket-driver` dependency (version 0.7.4), which handles WebSocket protocol framing and I/O. The fix upgrades the package to version 0.7.5 via an npm override in `package.json` and an updated lockfile, closing a WebSocket frame-parsing flaw that could allow attackers to inject or manipulate WebSocket traffic. This dependency-level fix is essential because the vulnerable library sits in the application's dependency tree and proce

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

Answer Summary

CVE-2026-54466 is a critical WebSocket frame-parsing vulnerability in the Node.js `websocket-driver` library (version 0.7.4) that could allow attackers to inject malicious frames or hijack WebSocket connections. It is related to CWE-94 (Improper Control of Generation of Code) and broader input-validation weaknesses. The fix is to upgrade `websocket-driver` to version 0.7.5 by adding an npm override in `package.json` and regenerating `package-lock.json`.

Vulnerability at a Glance

cweCWE-94 / CWE-1395
fixUpgrade websocket-driver from 0.7.4 to 0.7.5 via npm override
riskAttackers can inject or manipulate WebSocket frames, potentially hijacking connections or executing arbitrary actions
languageJavaScript (Node.js)
root causewebsocket-driver 0.7.4 improperly handles untrusted WebSocket frame data during parsing
vulnerabilityVulnerable third-party dependency (WebSocket frame injection)

Introduction

In this project's dependency tree, a critical vulnerability was lurking inside websocket-driver version 0.7.4—a widely-used Node.js library responsible for parsing and generating WebSocket protocol frames. Flagged by Trivy as CVE-2026-54466, this flaw sits at the intersection of untrusted network input and protocol-level parsing, meaning any application accepting WebSocket connections through this library was potentially exposed.

What makes this particularly dangerous is the context in which websocket-driver operates. The application already has concerns around plugin execution privileges (as noted in unchain_runtime/server/route_memory.py, where plugins execute with full Node.js runtime access to the filesystem, network, and child processes). A WebSocket-level vulnerability in this environment doesn't just risk connection hijacking—it could serve as an entry point that, combined with the unsandboxed plugin runtime, gives an attacker a path from a crafted WebSocket frame to full system access.

The fix is deceptively simple—a version bump from 0.7.4 to 0.7.5—but the implications of not applying it are severe. Let's dig into exactly what went wrong and how it was resolved.

The Vulnerability Explained

What is websocket-driver?

websocket-driver is a low-level Node.js library that implements the WebSocket protocol (RFC 6455). It handles the byte-level parsing of WebSocket frames: reading opcodes, masking keys, payload lengths, and reassembling fragmented messages. It's used by higher-level libraries like faye-websocket and often appears deep in dependency trees of frameworks like Webpack Dev Server, Socket.IO, and others.

What went wrong in version 0.7.4?

CVE-2026-54466 describes a flaw in how websocket-driver 0.7.4 parses incoming WebSocket frames from untrusted clients. The library's pluggable I/O architecture means it accepts raw byte streams and interprets them according to the WebSocket protocol. In the vulnerable version, certain malformed or specially crafted frame sequences were not properly validated, allowing an attacker to:

  1. Inject malicious frames that the server interprets as legitimate messages
  2. Manipulate the frame-parsing state machine to desynchronize the server's view of the connection from the client's
  3. Potentially smuggle data past application-level validation that trusts the WebSocket layer

A concrete attack scenario

Consider the application's architecture: it uses WebSocket connections (served through the dependency chain that includes websocket-driver) and runs plugins with full Node.js runtime privileges (as documented in unchain_runtime/server/route_memory.py). Here's how an attacker could chain these issues:

  1. An attacker connects to the application's WebSocket endpoint
  2. They send a specially crafted sequence of WebSocket frames that exploits the parsing flaw in websocket-driver 0.7.4
  3. The injected frame contains a command or message that the application's plugin system interprets as a legitimate instruction
  4. Because plugins execute without sandboxing—with full access to fs, net, and child_process—the injected command triggers file system access, network exfiltration, or arbitrary command execution

Even without the plugin escalation path, the WebSocket frame injection alone is critical: it breaks the fundamental trust boundary that the WebSocket protocol is supposed to enforce between client and server.

Why was this hard to catch?

The vulnerable code lives in package-lock.json as a transitive dependency. The project doesn't directly depend on websocket-driver—it's pulled in by another package in the dependency tree. This means:

  • It doesn't appear in the project's package.json dependencies
  • Standard code review wouldn't catch it
  • Only an SCA (Software Composition Analysis) scanner examining the full resolved dependency tree would flag it

Here's what the vulnerable lockfile entry looked like:

"node_modules/websocket-driver": {
  "version": "0.7.4",
  "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz",
  "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==",
  "license": "Apache-2.0",
  "dependencies": {
    "http-parser-js": ">=0.5.1",

Version 0.7.4 is the vulnerable version. The integrity hash confirms this is the exact artifact with the flaw.

The Fix

The fix involves two coordinated changes across package.json and package-lock.json:

1. Adding an npm override in package.json

Because websocket-driver is a transitive dependency (not directly listed in dependencies or devDependencies), a simple version bump in package.json wouldn't work. Instead, the fix uses npm's overrides mechanism to force the entire dependency tree to resolve to the patched version:

Before:

"overrides": {
  "shell-quote": "1.9.0"
}

After:

"overrides": {
  "shell-quote": "1.9.0",
  "websocket-driver": "0.7.5"
}

The overrides field in package.json tells npm: "No matter which package depends on websocket-driver, resolve it to version 0.7.5." This is the correct approach for patching transitive dependencies without restructuring the entire dependency tree.

Note that shell-quote was already being overridden for a previous security fix—this pattern of accumulating overrides for transitive dependency vulnerabilities is common in mature projects.

2. Updating package-lock.json

The lockfile was regenerated to reflect the new resolved version:

Before:

"node_modules/websocket-driver": {
  "version": "0.7.4",
  "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz",
  "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==",

After:

"node_modules/websocket-driver": {
  "version": "0.7.5",
  "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.5.tgz",
  "integrity": "sha512-ZL2+3c7kMBdIRCMz6l8jQMHyGVxj+UL+xVk74Ombiciboca8rHa15L86B19E5oh1pL9Ii/uj54gtsIrZGMo6zA==",

Both the version number and integrity hash changed, confirming that a genuinely different (patched) artifact is now being installed.

Why both files must change

  • package.json: Declares the override intent—without this, a future npm install could resolve back to 0.7.4
  • package-lock.json: Records the actual resolved version—without this update, existing CI/CD pipelines using npm ci (which installs from the lockfile) would continue installing the vulnerable version

Behavior preservation

The websocket-driver 0.7.5 release is a patch-level semver bump. It tightens input validation on WebSocket frame parsing but does not change the public API. Valid WebSocket frames are handled identically; only malformed/malicious frames are now properly rejected. This means the fix has zero impact on legitimate application behavior.

Prevention & Best Practices

1. Automate dependency scanning in CI/CD

Integrate tools like Trivy, Snyk, or npm audit into your CI pipeline so that every pull request is checked against the latest CVE databases:

# Example GitHub Actions step
- name: Run Trivy vulnerability scanner
  uses: aquasecurity/trivy-action@master
  with:
    scan-type: 'fs'
    scan-ref: '.'
    severity: 'CRITICAL,HIGH'

2. Use npm overrides for transitive dependency fixes

When a vulnerability exists in a transitive dependency, don't wait for the intermediate package to update. Use overrides (npm 8.3+) or resolutions (Yarn) to force the patched version:

{
  "overrides": {
    "vulnerable-package": ">=patched.version"
  }
}

3. Audit your WebSocket attack surface

If your application accepts WebSocket connections, ensure that:
- Frame parsing libraries are up to date
- Application-level message validation doesn't rely solely on the WebSocket layer for integrity
- Rate limiting and connection throttling are in place

4. Address the plugin sandboxing gap

The broader context of this fix highlights a compounding risk: unsandboxed plugins (unchain_runtime/server/route_memory.py) combined with a network-level vulnerability creates a critical escalation path. Consider implementing:
- A manifest-based permission system for plugins
- Node.js --experimental-permission flags or vm2/isolated-vm for plugin isolation
- Principle of least privilege for plugin filesystem and network access

5. Reference standards

  • CWE-94: Improper Control of Generation of Code ('Code Injection')
  • CWE-1395: Dependency on Vulnerable Third-Party Component
  • OWASP A06:2021: Vulnerable and Outdated Components

Key Takeaways

  • Transitive dependencies are a hidden attack surface: websocket-driver wasn't listed in package.json but was still exploitable—lockfile scanning is essential.
  • npm overrides are the correct mechanism for transitive dependency patches: Directly editing package-lock.json without the corresponding override in package.json will not persist across installs.
  • WebSocket frame parsing flaws are protocol-level vulnerabilities: They bypass application-layer validation because the application trusts the WebSocket layer to deliver well-formed messages.
  • Vulnerability chaining multiplies risk: CVE-2026-54466 alone is critical, but combined with the unsandboxed plugin execution in unchain_runtime/server/route_memory.py, it becomes a potential remote code execution vector.
  • Patch-level semver bumps (0.7.4 → 0.7.5) can carry critical security fixes: Don't ignore minor version changes in security-sensitive libraries.

How Orbis AppSec Detected This

  • Source: Incoming WebSocket frame data from untrusted network clients, parsed by the websocket-driver library in the application's dependency tree
  • Sink: The WebSocket frame-parsing logic in websocket-driver 0.7.4, which improperly validated frame sequences, allowing injection into the application's message handling pipeline
  • Missing control: No input validation or integrity check on malformed WebSocket frame sequences at the library level; no npm override forcing a patched version of the transitive dependency
  • CWE: CWE-94 (Improper Control of Generation of Code) and CWE-1395 (Dependency on Vulnerable Third-Party Component)
  • Fix: Added an npm override pinning websocket-driver to version 0.7.5 in package.json and regenerated package-lock.json to resolve the patched artifact

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 textbook example of why dependency management is a first-class security concern. A single transitive dependency—websocket-driver 0.7.4—introduced a critical WebSocket frame injection vulnerability that could be exploited by any network-connected attacker. The fix was a targeted, two-file change: an npm override in package.json and an updated package-lock.json, upgrading to the patched 0.7.5 release.

For teams running Node.js applications with WebSocket endpoints, this is a reminder to scan your full dependency tree (not just direct dependencies), use overrides to patch transitive vulnerabilities immediately, and consider the compounding risks when vulnerable network-facing code interacts with privileged runtime environments. Security is only as strong as its weakest transitive dependency.

References

Frequently Asked Questions

What is CVE-2026-54466?

CVE-2026-54466 is a critical vulnerability in the websocket-driver Node.js package (version 0.7.4) where improper handling of WebSocket frame data allows attackers to inject malicious frames or manipulate WebSocket protocol communication.

How do you prevent vulnerable dependency issues in Node.js?

Use automated dependency scanners like Trivy, Dependabot, or Orbis AppSec; pin dependency versions; use npm overrides for transitive dependencies; and regularly audit your dependency tree with `npm audit`.

What CWE is this vulnerability?

This vulnerability maps to CWE-94 (Improper Control of Generation of Code / Code Injection) and CWE-1395 (Dependency on Vulnerable Third-Party Component).

Is simply running npm audit enough to prevent vulnerable dependencies?

No. `npm audit` catches known vulnerabilities but may miss transitive dependencies or newly disclosed CVEs. Combining it with CI-integrated scanners like Trivy and automated fix tools provides more comprehensive coverage.

Can static analysis detect vulnerable dependencies?

Yes. Software Composition Analysis (SCA) tools like Trivy, Snyk, and Orbis AppSec scan lockfiles and dependency manifests to identify known vulnerable versions, even deep in the transitive dependency tree.

View the Security Fix

Check out the pull request that fixed this vulnerability

View PR #238

Related Articles

high

How Missing Minimum Release Age Configuration in pnpm Workspaces Happens and How to Fix It

A Node.js library's pnpm workspace configuration lacked the `minimumReleaseAge` setting, leaving it vulnerable to malicious or unstable newly-published packages. By adding a 7-day waiting period (10,080 minutes) along with additional hardening measures like `blockExoticSubdeps` and `trustPolicy`, the project now has robust defense against supply chain attacks targeting its dependencies.

critical

How CORS Misconfiguration happens in Node.js with Hono and how to fix it

CVE-2026-54290 is a HIGH severity CORS misconfiguration in the Hono web framework where the CORS middleware incorrectly reflects any `Origin` header back to the client — including credentials — when the `origin` option defaults to a wildcard. Upgrading `hono` from `4.12.16` to `4.12.34` in `package-lock.json` and pinning the version via `overrides` in `package.json` closes the vulnerability. Left unpatched, this flaw could allow malicious cross-origin sites to make credentialed requests and read

high

How Denial of Service via Infinite Loop happens in Node.js and how to fix it

A critical Denial of Service vulnerability (CVE-2026-67213) in the nanoid package allowed attackers to trigger infinite loops during random ID generation. This fix upgrades nanoid from version 3.3.11 to 3.3.18 using npm overrides, eliminating the infinite loop condition in the customAlphabet function that could crash Node.js applications.

high

How package_managers.pnpm.pnpm-missing-minimum-release-age.pnpm-minimum-release-age happens in pnpm workspaces and how to fix it

A pnpm workspace configuration was missing the `minimumReleaseAge` setting, allowing freshly published (and potentially malicious) package versions to be installed immediately. The fix adds a 7-day quarantine period along with `blockExoticSubdeps` and `trustPolicy: no-downgrade` to harden the supply chain against package takeover attacks.

critical

How WebSocket Protocol Handler Vulnerabilities happen in Node.js Dependencies and how to fix it

A critical vulnerability (CVE-2026-54466) was discovered in websocket-driver version 0.7.4, a WebSocket protocol handler used in the dependency tree. The vulnerability allowed attackers to exploit flaws in WebSocket frame parsing, potentially leading to denial of service or protocol-level attacks. The fix upgraded websocket-driver to version 0.7.5, which patches the protocol handling vulnerabilities and hardens input validation for untrusted WebSocket frames.

critical

How Server-Side Request Forgery (SSRF) Happens in Node.js fetch Tools and How to Fix It

A critical Server-Side Request Forgery (SSRF) vulnerability in `plugins/tools/fetch.js` allowed attackers to access internal resources and cloud metadata endpoints by passing arbitrary URLs to the fetch command. The fix adds hostname resolution and private IP range validation before executing any HTTP requests, preventing attackers from targeting internal infrastructure.