vm2 Sandbox Escape via node:sqlite Extension Loading Enables Native Code Execution (CVE-2026-92938)
A newly published GitHub Security Advisory (GHSA-6w8r-xxw2-g3hx) discloses a critical sandbox escape in vm2 3.11.6, tracked as CVE-2026-92938 with a CVSS score of 9.9. According to the advisory, when a host application allows the node:sqlite builtin inside NodeVM — either explicitly or via a wildcard builtin: ['*'] allowlist — sandboxed code can reach it using the alternate require path require('node:node:sqlite'). This bypasses vm2's resolver logic and returns the real host module wrapped only in a read-only proxy, which blocks property reassignment but does not restrict method calls.
From there, the advisory describes sandboxed code creating an in-memory DatabaseSync with extension loading enabled and calling loadExtension() on a native library bundled alongside the untrusted plugin (located via the plugin's own __dirname). SQLite loads that library directly into the Node.js host process and executes its native entry point — achieving arbitrary native code execution outside the sandbox, with no dependency on fs, child_process, process, or any other commonly restricted builtin. A working, harmless-by-design PoC is included in the advisory.
Why It Matters
This is a full sandbox escape, not an information leak or DoS. Any plugin platform, multi-tenant code runner, automation service, notebook environment, or build service that executes untrusted JavaScript via vm2's NodeVM and permits the node:sqlite builtin (or allows all builtins) is a plausible target. Per the advisory, exploitation requires only that the attacker-supplied package already contains a compatible native library on disk — no pre-existing host execution or writable database is needed. Successful exploitation hands the attacker OS-level privileges equal to the host Node.js process: credential theft, cross-tenant data access, persistence, or process disruption are all in scope.
What Defenders Should Do Now
- Inventory exposure: Identify any service using
vm2'sNodeVMwith a builtin allowlist, and check whethernode:sqliteis explicitly listed or reachable via a wildcard. - Restrict builtins immediately: Remove
node:sqlitefrom allowlists for any sandbox executing untrusted code until a fix is available; avoid `builtin: ['*']` entirely for untrusted-code sandboxes. - Hunt for anomalous native loads: Look for unexpected shared library (`.so`/`.dylib`/`.dll`) load events originating from Node.js host processes that run sandboxing frameworks, especially libraries located in plugin/package directories rather than system library paths.
- Review process-level isolation: Treat vm2's JavaScript-level sandboxing as insufficient alone for untrusted code; layer OS-level isolation (containers, seccomp, separate low-privilege processes) around any
NodeVMinstance. - Watch for vendor guidance: vm2 is an unmaintained/legacy project in parts of the ecosystem — confirm whether a patched release is forthcoming or whether migration to an actively maintained sandboxing library is warranted.
This is developing, same-day intel based on a single GHSA advisory; details may be refined as the maintainer and community respond. For the full technical writeup, PoC, and advisory updates, see the original source: GHSA-6w8r-xxw2-g3hx.