Advisories for Npm/Vm2 package

2026

vm2's Bridge Proxy set trap ignores receiver parameter, enabling host object property injection via prototype chain

The BaseHandler.set trap in bridge.js (line 1231) ignores the receiver parameter and unconditionally writes to the host target object. Per the Proxy set trap specification, when receiver !== proxy (e.g., when a child object inherits from the proxy via Object.create), the property assignment should create an own property on the receiver, not on the proxy target. The current implementation always calls otherReflectSet(object, key, value) against the host target, causing all …

vm2 setup-sandbox.js violates Defense Invariant #11 in stack-trace formatter

defaultSandboxPrepareStackTrace in lib/setup-sandbox.js (lines 605, 607) appends to a fresh sandbox-realm lines = [] via lines[lines.length] = value. This is the exact invariant-violating pattern that GHSA-9qj6-qjgg-37qq (commit ca195f0, 2026-05-01) just patched in neutralizeArraySpeciesBatch and codified as Defense Invariant #11 ("Bridge-internal containers must not invoke sandbox code"). A sandbox-installed Array.prototype[N] setter fires during the bridge's safe-default stack-trace formatting and observes / intercepts each appended line.

vm2 sandbox escape via JSPI-backed Promise `.finally()` species bypass

A sandbox escape vulnerability in vm2 allows arbitrary code execution in the host process when untrusted code is executed with async support on runtimes exposing WebAssembly JSPI (WebAssembly.promising / WebAssembly.Suspending). In the tested configuration, a JSPI-backed Promise can reach Promise.prototype.finally() in a way that bypasses the expected Promise-species hardening and exposes a host-originated rejection object to attacker-controlled species logic, breaking the sandbox boundary. This is a critical sandbox escape: any …

vm2 has a sandbox escape via unblocked cross-realm Symbol.for keys + missing bridge write-trap symbol checks

vm2 3.11.2 Symbol.for override in setup-sandbox.js only intercepts 2 of 9 dangerous Node.js cross-realm symbols. Combined with the bridge's set/defineProperty/deleteProperty traps having no isDangerousCrossRealmSymbol key check, sandbox code can obtain real cross-realm symbols, write them to host objects, and control host-side behavior — verified with a full util.promisify hijack chain.

vm2 has a Sandbox Escape issue

By combining Buffer.call.call({}.lookupGetter, Buffer, "proto"), Buffer.call.call({}.lookupSetter, Buffer, "proto"), and Node.js's ERR_INVALID_ARG_TYPE Error, the host's TypeError constructor can be obtained, which allows the escape from the sandbox. This allows attackers to run arbitrary code.

vm2 has a CVE-2023-37903 patch bypass: nesting:true without explicit require still allows full RCE

The fix for GHSA-8hg8-63c5-gwmx (CVE-2023-37903) introduced a check in nodevm.js line 263 that blocks the combination nesting: true + require: false. However, the check uses strict equality (options.require === false), which is trivially bypassed by omitting the require option entirely. When require is not specified, options.require is undefined, not false. The strict equality check fails, so the security guard is skipped. Immediately after (line 280), the destructuring default require: requireOpts …

NodeVM observability builtins leak host process and HTTP request data

NodeVM exposes some process-wide observability builtins when they are allowed through require.builtin. The following builtins are not blocked by the dangerous builtin denylist: diagnostics_channel async_hooks perf_hooks These modules are process-wide, not sandbox-local. Sandboxed code can use them to observe host application data across the vm2 boundary. Note: It is a host data exposure issue. The impact depends on whether the host application allows these builtins and uses HTTP, async request …

NodeVM network builtin exclusions bypass via internal _http_client and _http_server

NodeVM supports excluding public network builtins from the wildcard builtin option. With this configuration direct access to http, https, http2, net, dgram, tls, dns, and dns/promises is blocked. However, Node.js also exposes underscored internal HTTP builtins such as _http_client and _http_server. These are not blocked when the public modules are excluded. Sandboxed code can use these internal builtins to make outbound HTTP requests and open listening HTTP sockets even though …

vm2's Transformer Fast-Path Bypass Exposes Internal State Variable

vm2's code transformer has a performance optimization that skips AST analysis when the code does not contain catch, import, or async keywords. This fast-path bypass allows sandboxed code to directly access the internal VM2_INTERNAL_STATE_DO_NOT_USE_OR_PROGRAM_WILL_FAIL variable, which exposes internal security functions (handleException, wrapWith, import).

vm2: Mutable Proxies for Host Intrinsic Prototypes Allows Sandbox Escape

vm2's bridge exposes mutable proxies for real host-realm intrinsic prototypes and then forwards sandbox writes into the underlying host objects with otherReflectSet() and otherReflectDefineProperty(), which lets attacker-controlled JavaScript running in a default VM or inherited NodeVM mutate shared host Object.prototype, Array.prototype, and Function.prototype from inside the sandbox.

vm2 NodeVM `nesting: true` bypasses `require: false` allowing sandbox escape and arbitrary OS command execution

When a NodeVM is created with nesting: true, sandbox code can unconditionally require('vm2') regardless of the outer VM's require configuration — including require: false. With access to vm2, the sandbox constructs a new inner NodeVM with its own unrestricted require settings and executes arbitrary OS commands on the host. Any application that runs untrusted code inside a NodeVM with nesting: true is fully compromised.

vm2 Host Promise Resolution Preserves Object Identity Across Sandbox Boundary

A sandbox boundary violation in vm2 allows host object identity to cross into the sandbox through host Promise resolution. When a host-side Promise that resolves to a host object is exposed to the sandbox, the value delivered to the sandbox .then() callback preserves host identity. This allows the sandbox to interact with the host object directly, including: Performing identity checks using host-side WeakMap Mutating host object state from inside the …

vm2 has a NodeVM require.root bypass via symlink traversal that allows sandbox escape

NodeVM's require.root path restriction can be bypassed using filesystem symlinks, allowing sandboxed code to load modules from outside the allowed root directory in host context. Because path validation uses path.resolve() (which does not dereference symlinks) but module loading uses Node's native require() (which does), an attacker can load arbitrary host-realm modules and achieve remote code execution.

vm2 has a NodeVM builtin allowlist bypass via `module` builtin's `Module._load` that allows sandbox escape

NodeVM's builtin allowlist can be bypassed when the module builtin is allowed (including via the '*' wildcard). The module builtin exposes Node's Module._load(), which loads any module by name directly in the host context, completely bypassing vm2's builtin restriction. This allows sandboxed code to load excluded builtins like child_process and achieve remote code execution.

vm2 has a Sandbox Escape

In vm2 for version 3.10.0, Promise.prototype.then Promise.prototype.catch callback sanitization can be bypassed. This allows attackers to escape the sandbox and run arbitrary code. const { VM } = require("vm2"); const code = ` const error = new Error(); error.name = Symbol(); const f = async () => error.stack; const promise = f(); promise.catch(e => { const Error = e.constructor; const Function = Error.constructor; const f = new Function( "process.mainModule.require('child_process').execSync('echo HELLO …

2023

Improper Neutralization of Special Elements in Output Used by a Downstream Component ('Injection')

vm2 is a sandbox that can run untrusted code with Node's built-in modules. In versions 3.9.17 and lower of vm2 it was possible to get a read-write reference to the node inspect method and edit options for console.log. As a result a threat actor can edit options for the console.log command. This vulnerability was patched in the release of version 3.9.18 of vm2. Users are advised to upgrade. Users unable …

Improper Neutralization of Special Elements in Output Used by a Downstream Component ('Injection')

vm2 is a sandbox that can run untrusted code with Node's built-in modules. A sandbox escape vulnerability exists in vm2 for versions up to and including 3.9.17. It abuses an unexpected creation of a host object based on the specification of Proxy. As a result a threat actor can bypass the sandbox protections to gain remote code execution rights on the host running the sandbox. This vulnerability was patched in …

Improper Neutralization of Special Elements in Output Used by a Downstream Component ('Injection')

vm2 is a sandbox that can run untrusted code with allow listed Node's built-in modules. There exists a vulnerability in exception sanitization of vm2 for versions up to 3.9.16, allowing attackers to raise an unsanitized host exception inside handleException() which can be used to escape the sandbox and run arbitrary code in host context. This vulnerability was patched in the release of version 3.9.17 of vm2. There are no known …

Improper Control of Dynamically-Managed Code Resources

vm2 is a sandbox that can run untrusted code with allow listed Node's built-in modules. Prior to version 3.9.15, vm2 was not properly handling host objects passed to Error.prepareStackTrace in case of unhandled async errors. A threat actor could bypass the sandbox protections to gain remote code execution rights on the host running the sandbox. This vulnerability was patched in the release of version 3.9.15 of vm2. There are no …

2022

Improper Control of Dynamically-Managed Code Resources

vm2 is a sandbox that can run untrusted code with allow listed Node's built-in modules. In versions prior to version 3.9.11, a threat actor can bypass the sandbox protections to gain remote code execution rights on the host running the sandbox. This vulnerability was patched in the release of version 3.9.11 of vm2. There are no known workarounds.

Uncontrolled Recursion

This affects the package vm2 before 3.6.11. It is possible to trigger a RangeError exception from the host rather than the "sandboxed" context by reaching the stack call limit with an infinite recursion. The returned object is then used to reference the mainModule property of the host code running the script allowing it to spawn a child_process and execute arbitrary code.

2021