Skip to main content

VM2 CVE-2026-24118

| EUVDEUVD-2026-26984 CRITICAL
Code Injection (CWE-94)
2026-05-04 https://github.com/patriksimek/vm2 GHSA-grj5-jjm8-h35p
9.8
CVSS 3.1 · Vendor: https://github.com/patriksimek/vm2
Share

Severity by source

Vendor (https://github.com/patriksimek/vm2) PRIMARY
9.8 CRITICAL
AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
Red Hat
9.1 HIGH
qualitative

Primary rating from Vendor (https://github.com/patriksimek/vm2).

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

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

Lifecycle Timeline

7
PoC Detected
May 04, 2026 - 17:16 vuln.today
Public exploit code
Source Code Evidence Fetched
May 04, 2026 - 17:03 vuln.today
Analysis Generated
May 04, 2026 - 17:03 vuln.today
EUVD ID Assigned
May 04, 2026 - 16:30 euvd
EUVD-2026-26984
Analysis Generated
May 04, 2026 - 16:30 vuln.today
Patch released
May 04, 2026 - 16:30 nvd
Patch available
CVE Published
May 04, 2026 - 16:29 nvd
CRITICAL 9.8

DescriptionCVE.org

Summary

VM2 suffers from a sandbox breakout vulnerability. This allows attackers to write code which can escape from the VM2 sandbox and execute arbitrary commands on the host system.

Details

The __lookupGetter__ method allows to read the getter of an object. It is special in VM2 since it will switch between the host and sandbox version of the method when passed to the other context. This allows to access getters on an object in the host context if the method is called from the host context which can be achieved by using the host apply method which can be accessed through Buffer.apply. Afterwards, this function can be used to call the host version of __lookupGetter__ with Buffer and __proto__ resulting in the prototype lookup method from the host context. With this method the hosts Function.prototype object can be retrieved and the host Function acquired through the constructor property which allows to create and run code in the host context. This issue was attempted to be fixed with https://github.com/patriksimek/vm2/blob/4b009c2d4b1131c01810c1205e641d614c322a29/lib/bridge.js#L427. However, this can be circumvented by using Object.getOwnPropertyDescriptor to get the constructor property.

PoC

The following code demonstrates this issue by acquiring the host process object and executing touch pwned.

js
const {VM} = require("vm2");
const vm = new VM();
vm.run(`
const g = ({}).__lookupGetter__;
const a = Buffer.apply;
const p = a.apply(g, [Buffer, ['__proto__']]);
Object.getOwnPropertyDescriptor(p.call(a),'constructor').value('return process')().mainModule.require('child_process').execSync('touch pwned');
`);

Impact

Attackers can perform Remote Code Execution under the assumption that arbitrary code can be executed inside the context of a vm2 sandbox.

AnalysisAI

Remote code execution in VM2 sandbox (npm package) versions ≤3.10.4 allows attackers to escape the JavaScript isolation boundary and execute arbitrary system commands on the host. The vulnerability exploits prototype chain traversal through Buffer.apply and __lookupGetter__ to access the host Function constructor, bypassing VM2's context isolation. Publicly available exploit code exists, and vendor-released patch version 3.11.0 addresses the issue. This is a complete sandbox escape requiring no authentication or user interaction, making it critical for environments executing untrusted code within VM2 contexts.

Technical ContextAI

VM2 is a Node.js npm package (pkg:npm/vm2) designed to provide sandboxed JavaScript execution environments. The vulnerability stems from CWE-94 (Improper Control of Generation of Code) in VM2's context isolation mechanism. The flaw lies in how VM2's bridge layer handles prototype chain traversal when switching between host and sandbox contexts. The __lookupGetter__ method is special-cased in VM2 to switch between host and sandbox versions, but this switching can be exploited. By chaining Buffer.apply (accessible from sandbox) with __lookupGetter__ and Object.getOwnPropertyDescriptor, an attacker can traverse from sandbox Buffer through __proto__ to the host's Function.prototype, then extract the host Function constructor. Previous fix attempts at blocking direct constructor access were bypassed using Object.getOwnPropertyDescriptor to indirectly retrieve the constructor property descriptor. The vulnerability demonstrates a fundamental challenge in JavaScript sandboxing: preventing prototype chain traversal across security boundaries when built-in objects must be shared between contexts.

RemediationAI

Upgrade to VM2 version 3.11.0 or later, which includes patches from commits 2b5f3e3a060d9088f5e1cdd585d683d491f990a3 and f9b700b1c7d9ef2df416666cb24e0b659140cc74 that block the descriptor chain exploit. The release is available at https://github.com/patriksimek/vm2/releases/tag/v3.11.0. If immediate upgrade is not possible, compensating controls include disabling VM2 usage entirely and replacing with alternative isolation mechanisms such as running untrusted code in dedicated containers (Docker), separate processes with strict resource limits (child_process with V8 isolates), or WebAssembly sandboxes. These alternatives trade performance and complexity for stronger isolation boundaries but eliminate JavaScript prototype chain traversal attacks. Note that attempting to filter specific method names (__lookupGetter__, Object.getOwnPropertyDescriptor) is ineffective due to the many alternate access paths in JavaScript. There is no safe workaround that keeps VM2 ≤3.10.4 in use for untrusted code. Organizations should also audit logs for suspicious VM2 usage patterns such as repeated sandbox creation failures or code containing prototype traversal keywords.

Vendor StatusVendor

Share

CVE-2026-24118 vulnerability details – vuln.today

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