CVE-2023-29017 Overview
CVE-2023-29017 is a sandbox escape vulnerability in vm2, a popular Node.js library designed to run untrusted code in a secure, isolated environment with whitelisted built-in modules. Prior to version 3.9.15, vm2 failed to properly handle host objects passed to Error.prepareStackTrace when processing unhandled async errors. This flaw allows a threat actor to bypass sandbox protections entirely, achieving remote code execution on the host system running the sandbox.
Critical Impact
Attackers can escape the vm2 sandbox and execute arbitrary code on the host system, completely compromising the security isolation that vm2 is designed to provide.
Affected Products
- vm2_project vm2 versions prior to 3.9.15
- Node.js applications utilizing vulnerable vm2 versions for sandboxing untrusted code
- Server-side JavaScript execution environments relying on vm2 for code isolation
Discovery Timeline
- 2023-04-06 - CVE-2023-29017 published to NVD
- 2024-11-21 - Last updated in NVD database
Technical Details for CVE-2023-29017
Vulnerability Analysis
This vulnerability represents a Sandbox Escape combined with Remote Code Execution (RCE). The vm2 library provides a sandboxed execution environment for untrusted JavaScript code, but the security boundary was compromised through improper handling of host objects during error stack trace preparation.
When an unhandled async error occurs within the sandbox, the Error.prepareStackTrace callback receives stack trace information as an array of CallSite objects. The vulnerability arises because vm2 did not adequately validate and wrap these host objects before passing them to sandboxed code. By exploiting this oversight, an attacker could access the host environment's objects and functions, effectively escaping the sandbox entirely.
The impact is severe as vm2 is specifically designed to execute untrusted code safely. Applications using vm2 for multi-tenant code execution, plugin systems, or serverless function sandboxing are at significant risk. Once the sandbox is escaped, attackers gain the same privileges as the Node.js process running vm2.
Root Cause
The root cause lies in the improper isolation of host objects passed through the Error.prepareStackTrace callback mechanism. When processing async errors, the stack trace array (sst) was passed directly to the sandboxed prepareStackTrace function without ensuring that the array itself was safely wrapped. This allowed attackers to manipulate the array or access prototype chains leading back to the host environment.
The fix introduces an ensureThis function call to create a sandbox-safe copy of the stack trace array and adds conditional logic to properly handle cases where the original array differs from the sandboxed version.
Attack Vector
The attack is network-based and can be executed without authentication or user interaction. An attacker with the ability to submit code for sandbox execution can craft malicious JavaScript that triggers an unhandled async error with a manipulated Error.prepareStackTrace callback, gaining access to host objects and achieving arbitrary code execution outside the sandbox.
// Security patch in lib/setup-sandbox.js - Wrap host objects passed through prepareStackTrace
// Source: https://github.com/patriksimek/vm2/commit/d534e5785f38307b70d3aac1945260a261a94d50
return;
}
const newWrapped = (error, sst) => {
+ const sandboxSst = ensureThis(sst);
if (localArrayIsArray(sst)) {
- for (let i=0; i < sst.length; i++) {
- const cs = sst[i];
- if (typeof cs === 'object' && localReflectGetPrototypeOf(cs) === OriginalCallSite.prototype) {
- sst[i] = new CallSite(cs);
+ if (sst === sandboxSst) {
+ for (let i=0; i < sst.length; i++) {
+ const cs = sst[i];
+ if (typeof cs === 'object' && localReflectGetPrototypeOf(cs) === OriginalCallSite.prototype) {
+ sst[i] = new CallSite(cs);
+ }
+ }
+ } else {
+ sst = [];
+ for (let i=0; i < sandboxSst.length; i++) {
+ const cs = sandboxSst[i];
+ localReflectDefineProperty(sst, i, {
+ __proto__: null,
+ value: new CallSite(cs),
+ enumerable: true,
+ configurable: true,
+ writable: true
+ });
}
}
+ } else {
Detection Methods for CVE-2023-29017
Indicators of Compromise
- Unexpected process spawning or network connections from Node.js applications using vm2
- Anomalous file system access patterns originating from sandboxed code execution contexts
- Error logs showing manipulation of Error.prepareStackTrace or unusual async error handling
- Memory or CPU usage spikes indicative of sandbox escape attempts
Detection Strategies
- Implement runtime monitoring to detect unexpected code execution paths escaping vm2 sandbox boundaries
- Audit application dependencies using npm audit or similar tools to identify vulnerable vm2 versions
- Deploy endpoint detection capable of identifying post-exploitation behaviors such as reverse shells or data exfiltration
- Monitor for suspicious patterns in error handling code, particularly around prepareStackTrace callbacks
Monitoring Recommendations
- Enable comprehensive logging for all sandboxed code execution events
- Implement network egress monitoring for Node.js processes utilizing vm2
- Deploy SentinelOne Singularity Platform to detect and prevent post-exploitation activities
- Establish baseline behavior profiles for applications using vm2 to identify anomalous activity
How to Mitigate CVE-2023-29017
Immediate Actions Required
- Upgrade vm2 to version 3.9.15 or later immediately
- Audit all applications and dependencies to identify vm2 usage
- Consider temporarily disabling sandboxed code execution features until patching is complete
- Review application logs for evidence of exploitation attempts
Patch Information
The vulnerability was patched in vm2 version 3.9.15. The fix modifies lib/setup-sandbox.js to properly wrap host objects passed through Error.prepareStackTrace by introducing the ensureThis function and additional validation logic. Organizations should update via npm:
For detailed patch information, see the GitHub Security Advisory and the commit fixing the vulnerability.
Workarounds
- No known workarounds exist for this vulnerability
- Upgrading to version 3.9.15 or later is the only effective mitigation
- Consider alternative sandboxing solutions if immediate patching is not feasible
- Implement additional defense-in-depth measures such as containerization or process isolation
# Update vm2 to patched version
npm update vm2@3.9.15
# Verify installed version
npm list vm2
# Audit dependencies for vulnerable packages
npm audit
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.


