TL;DR: Vm2 has a critical 9.8 CVSS vulnerability that lets attackers bypass promise sanitization and execute arbitrary code inside the Node.js process, affecting versions 3.10.1 and earlier, according to Semgrep. The case reinforces that code sanitization is not a substitute for real isolation when untrusted input can reach execution paths.
Editorial analysis by NHI Mgmt Group, based on content published by Semgrep: “New Sandbox Escape Affecting Popular nodejs Sandbox library vm2”.
Key questions
Q: What breaks when a JavaScript sandbox fails to sanitise all Promise paths?
A: The entire containment model breaks, because untrusted code can cross from restricted execution into host-level execution through the unsanitised path.
Q: Why do in-process sandboxes increase the impact of untrusted code bugs?
A: Because the guest code and the application share the same runtime.
Q: How can security teams tell whether a sandbox model is too fragile for production use?
A: Look for repeated bypasses, reliance on language-level interception, and any design where hostile code can influence asynchronous control flow.
Practitioner guidance
- Upgrade vm2 to the fixed release Move all deployments using vm2 3.10.1 or earlier to version 3.10.2 and verify the affected package is not pinned indirectly through dependencies.
- Inventory every untrusted-code execution path Map where user-provided or externally influenced JavaScript, templates, or expressions can reach vm2 or similar sandboxes, including internal tools that may later become externally reachable.
- Replace in-process sandboxes for high-risk code Use containerized execution or native isolate-based separation where untrusted code must run, and treat JavaScript-level promise sanitization as a secondary safeguard only.
Bottom line: The central issue is not a bad regex or a weak filter. It is a sandbox design that can be crossed from inside the same process it is supposed to protect.
Explore further
View Full Forum → | NHI Foundation Course → | Our Services → | Read the full analysis →
Promise sanitization is not a trust boundary: the article shows that asynchronous control flow can create fail-open paths even when a sandbox appears to be instrumented correctly. That matters because many application teams confuse input filtering with execution containment. The practical conclusion is that sanitization may reduce noise, but only isolation defines the security boundary.
A question worth separating out:
Q: When should teams choose containerised or isolate-based execution over sanitisation?
A: Choose stronger isolation when untrusted code can originate from users, plugins, templates, or any path that might later become externally reachable. Sanitisation may still help, but it should not be the only barrier. Once the application could face arbitrary input, the containment boundary must sit outside the application process.
👉 Read our full editorial: Vm2 sandbox escapes expose the limits of promise sanitization