Skip to content

[GHSA-ffh4-j6h5-pg66] VM2 Has a WASM Sandbox Escape (Node 25 only)#7613

Open
Wenxin-Jiang wants to merge 2 commits intoWenxin-Jiang/advisory-improvement-7613from
Wenxin-Jiang-GHSA-ffh4-j6h5-pg66
Open

[GHSA-ffh4-j6h5-pg66] VM2 Has a WASM Sandbox Escape (Node 25 only)#7613
Wenxin-Jiang wants to merge 2 commits intoWenxin-Jiang/advisory-improvement-7613from
Wenxin-Jiang-GHSA-ffh4-j6h5-pg66

Conversation

@Wenxin-Jiang
Copy link
Copy Markdown

@Wenxin-Jiang Wenxin-Jiang commented May 7, 2026

Updates

  • Affected products
  • Summary

Comments
The current advisory underspecifies both the affected vm2 range and the affected Node.js range. Empirical testing demonstrates:

  1. The vulnerability affects all vm2 versions prior to 3.10.5 (the advisory currently flags only = 3.10.4).
  2. The vulnerability is exploitable on any Node.js runtime that exposes WebAssembly.JSTag — this includes Node.js 24.x, not just Node.js 25.x as the title implies. Node.js 26+ will continue to be affected.

The advisory's Details section already states the correct precondition ("Node.js version with WebAssembly exception handling + JSTag support"), but the title ("Node 25 only") and the parenthetical "(tested on v25.6.1)" cause downstream tooling and readers to interpret the impact too narrowly.

Supporting evidence

A. Fix is purely additive and equally absent from earlier versions

The fix shipped in vm2 v3.10.5 (already linked from the advisory's references).

localReflectDeleteProperty(WebAssembly, 'JSTag');

That deletion does not exist in 3.10.4 — but it also does not exist in 3.10.3, 3.10.0, 3.9.x, 3.0.0, or any earlier release. Every pre-3.10.5 version exposes the unsanitized WebAssembly.JSTag to sandboxed code, which is the entire root cause described in the advisory's PoC. There is no logical basis for restricting the affected range to a single point version.

B. Empirical confirmation across the full vm2 version history

I ran the advisory's own PoC pattern (sandbox escape via WebAssembly.JSTag → host-side try/catch capture → process.mainModule.require('child_process').execSync) — using the byte-for-byte WebAssembly module from the published PoC — against every loadable historical vm2 release on Node.js v24.15.0:

Outcome Count Versions
Sandbox escape succeeded 66 0.2.2 → 3.10.4 (every release in this range)
Patched (escape blocked, expected error) 4 3.10.5, 3.11.0, 3.11.1, 3.11.2
Refuses to load on modern Node 4 0.1.0, 0.1.1, 0.2.0, 0.2.1 - engine check rejects Node ≥ 1.0

The fixed versions act as a clean negative control: the same exploit fails with WebAssembly.Instance(): Import #1 "js" "tag" tag must be a WebAssembly.Tag once JSTag is deleted, exactly as the fix intends.
Earlier releases (0.1.0–0.2.1) refuse to load due to an engine-check regex (/^0.[1-9][1-9]./) that only matches Node 0.1x.x; they only run on Node versions that predate WebAssembly.JSTag and are therefore unaffected in practice.

C. Node.js 24 is affected — and Node.js 26 will continue to be

WebAssembly.JSTag is the JS-API binding for the WebAssembly Exception Handling proposal, which reached stage 4 and shipped in V8 11.9. Once a stage-4 standard ships in V8, it is not removed in later versions.

  • Node.js 24 ships V8 13.x and exposes WebAssembly.JSTag.
  • Node.js 25 ships V8 14.1 (per the v25.0.0 changelog) — this is where the reporter happened to test.
  • Node.js 26 (April 2026 "Current") ships an even newer V8 and continues to expose WebAssembly.JSTag.

Direct probe on Node.js v24.15.0:

$ node --version
v24.15.0
$ node -e "console.log(typeof WebAssembly.JSTag)"
object

All 66 successful exploitations above were performed on Node v24.15.0. The "Node 25 only" wording is therefore both too high on the lower bound (excludes Node 24, which is in active use) and misleading on the upper end (implies 26+ might somehow not be affected — they are, until/unless vm2 is upgraded to ≥ 3.10.5).

D. Practical impact

Restricting the advisory to vm2 = 3.10.4 causes downstream scanners and SCA tools to mark the vast majority of vm2 deployments as unaffected, even though they are exploitable today on any Node.js 24+ runtime. Given that vm2 is already deprecated and unmaintained, an accurate range is critical for users still depending on older versions to make an informed migration decision (and for SCA tools to surface the issue at all).

@github
Copy link
Copy Markdown
Collaborator

github commented May 7, 2026

Hi there @patriksimek! A community member has suggested an improvement to your security advisory. If approved, this change will affect the global advisory listed at github.com/advisories. It will not affect the version listed in your project repository.

This change will be reviewed by our Security Curation Team. If you have thoughts or feedback, please share them in a comment here! If this PR has already been closed, you can start a new community contribution for this advisory

@github-actions github-actions Bot changed the base branch from main to Wenxin-Jiang/advisory-improvement-7613 May 7, 2026 22:18
@github
Copy link
Copy Markdown
Collaborator

github commented May 7, 2026

Hi there @patriksimek! A community member has suggested an improvement to your security advisory. If approved, this change will affect the global advisory listed at github.com/advisories. It will not affect the version listed in your project repository.

This change will be reviewed by our Security Curation Team. If you have thoughts or feedback, please share them in a comment here! If this PR has already been closed, you can start a new community contribution for this advisory

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants