← Blog · · df00tech

vm2 Sandbox Escape: Fix for GHSA-m283-3h24-438v Bypassed via call/apply Indirection, PoC Public

breaking ghsa npm CVE-2026-92937

What happened

A newly published GHSA advisory (GHSA-647f-g98j-qq25, tracked as CVE-2026-92937) reports that the prior fix for vm2 vulnerability GHSA-m283-3h24-438v is incomplete. According to the advisory, vm2's bridge code sanitizes host Promise rejection values before they reach sandboxed callbacks, but the sanitization gate at lib/bridge.js:1624 only identity-checks the direct call target. Registering a rejection handler through Function.prototype.call or .apply indirection (e.g. p.then.call(p, undefined, cb)) causes the sanitizer to be skipped, so a raw host error object reaches sandbox code unmodified.

The advisory includes a working proof-of-concept: when an embedder-exposed async host function throws an Error with a non-primitive own property referencing a powerful host object (e.g. err.detail = process), sandboxed code can use the call-indirection bypass to reach that property and invoke require('child_process').execSync(...), achieving command execution in the host Node.js process. The advisory notes the bind and Reflect.apply forms remain sanitized — the bypass is isolated to call/apply indirection.

Why it matters

This is rated CVSS 10.0 with a public PoC. Any application using vm2 to evaluate untrusted or third-party JavaScript — and that bridges a host-realm Promise into the sandbox, whether via the sandbox option or a NodeVM external module's async method — is potentially affected if a rejecting Error can carry a host object reference as an own property. The advisory specifically flags this as a routine pattern for Node diagnostic/error objects, meaning it may occur without any deliberate embedder action. In multi-tenant code-execution services (plugin platforms, code-challenge graders, serverless function sandboxes), a single malicious submission could compromise the worker process and every tenant it serves.

What defenders should do now

  • Inventory any services using vm2 for untrusted-code execution and check whether they bridge host async functions or Promises into the sandbox.
  • Treat vm2 as unsuitable for strong security isolation of untrusted code pending an upstream fix — the project has a known history of incomplete sandbox-escape fixes; consider migrating to OS/VM-level isolation (containers, gVisor, Firecracker, or a separate process with restricted privileges) rather than relying on in-process JS sandboxing.
  • As a hunting angle, review application and host logs for anomalous child-process spawns or require('child_process') usage originating from worker/sandbox processes that should never shell out.
  • If patching isn't immediately possible, consider auditing or stripping non-primitive own properties from Errors thrown by any host functions exposed to the sandbox, and monitor for unexpected use of .call/.apply patterns in submitted code where static analysis is feasible.

Developing intel

This is a same-day advisory and the full scope of affected deployments and any official vendor remediation timeline is still emerging. Treat details here as preliminary pending further analysis. See the original GitHub Security Advisory for the authoritative technical write-up: GHSA-647f-g98j-qq25.

Get new detections in your inbox

New ATT&CK coverage plus CISA KEV / CVE detection rules, roughly weekly. No spam, unsubscribe anytime.