{"description":"Trending threats, MITRE ATT\u0026CK coverage, and detection metadata. Fed continuously.","favicon":"https://feed.craftedsignal.io/favicon-32x32.png","feed_url":"https://feed.craftedsignal.io/products/vm2--3.9.6--3.11.5/feed.json","home_page_url":"https://feed.craftedsignal.io/","icon":"https://feed.craftedsignal.io/apple-touch-icon.png","items":[{"_cs_actors":[],"_cs_cpes":["cpe:2.3:a:vm2_project:vm2:*:*:*:*:*:node.js:*:*"],"_cs_cves":[{"cvss":9.9,"id":"CVE-2026-92948"}],"_cs_exploited":false,"_cs_has_poc":false,"_cs_poc_references":[],"_cs_products":["vm2 (\u003e= 3.9.6, \u003c= 3.11.5)"],"_cs_severities":["critical"],"_cs_tags":["sandbox-escape","nodejs","code-execution"],"_cs_type":"advisory","_cs_vendors":[],"content_html":"\u003cp\u003eThe vm2 library (versions 3.9.6 through 3.11.5) contains a critical sandbox escape vulnerability (CVE-2026-92948) when running on Node.js 24 or newer. The issue arises from a failure to correctly restrict the \u003ccode\u003enode:test\u003c/code\u003e builtin module. When an embedder explicitly allows \u003ccode\u003enode:test\u003c/code\u003e within a \u003ccode\u003eNodeVM\u003c/code\u003e configuration, sandboxed code can bypass the intended restrictions by requesting the module using a double prefix, \u003ccode\u003erequire('node:node:test')\u003c/code\u003e.\u003c/p\u003e\n\u003cp\u003eNormalization logic within \u003ccode\u003evm2\u003c/code\u003e resolves this to the \u003ccode\u003enode:test\u003c/code\u003e module, providing the sandbox with a readonly proxy to the host's test-runner. Because this proxy forwards calls to the host implementation without sufficient API validation, an attacker can invoke \u003ccode\u003enode:test.run()\u003c/code\u003e and supply arbitrary \u003ccode\u003eexecArgv\u003c/code\u003e flags. By passing flags such as \u003ccode\u003e--eval\u003c/code\u003e, the attacker can spawn a child process that executes arbitrary JavaScript in an unrestricted host Node.js environment, effectively escaping the vm2 sandbox boundary.\u003c/p\u003e\n\u003ch2 id=\"attack-chain\"\u003eAttack Chain\u003c/h2\u003e\n\u003col\u003e\n\u003cli\u003eAttacker identifies a target application utilizing \u003ccode\u003evm2\u003c/code\u003e with \u003ccode\u003enode:test\u003c/code\u003e explicitly enabled in the \u003ccode\u003erequire.builtin\u003c/code\u003e configuration.\u003c/li\u003e\n\u003cli\u003eAttacker injects malicious JavaScript into the \u003ccode\u003eNodeVM\u003c/code\u003e sandbox environment.\u003c/li\u003e\n\u003cli\u003eAttacker invokes \u003ccode\u003erequire('node:node:test')\u003c/code\u003e within the sandbox to bypass existing builtin restriction filters.\u003c/li\u003e\n\u003cli\u003eThe \u003ccode\u003evm2\u003c/code\u003e sandbox normalizes the path to \u003ccode\u003enode:test\u003c/code\u003e and grants access to the host's test-runner module.\u003c/li\u003e\n\u003cli\u003eAttacker executes \u003ccode\u003enode:test.run()\u003c/code\u003e within the sandbox, supplying a crafted object containing malicious \u003ccode\u003eexecArgv\u003c/code\u003e parameters.\u003c/li\u003e\n\u003cli\u003eThe \u003ccode\u003enode:test\u003c/code\u003e runner spawns a new Node.js child process using the attacker-supplied \u003ccode\u003eexecArgv\u003c/code\u003e arguments.\u003c/li\u003e\n\u003cli\u003eThe child process executes the attacker's payload (e.g., \u003ccode\u003e--eval='require(\u0026quot;fs\u0026quot;).writeFileSync(...)'\u003c/code\u003e) outside the sandbox, granting full access to the host system.\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch2 id=\"impact\"\u003eImpact\u003c/h2\u003e\n\u003cp\u003eSuccessful exploitation allows an attacker to break out of the vm2 sandbox and execute code with the privileges of the host Node.js process. This leads to full system compromise, including unauthorized access to the host filesystem, environment variables, network resources, and other sensitive host-side data. The impact is critical as it invalidates the security boundary provided by the vm2 library.\u003c/p\u003e\n\u003ch2 id=\"recommendation\"\u003eRecommendation\u003c/h2\u003e\n\u003col\u003e\n\u003cli\u003eUpgrade to a patched version of \u003ccode\u003evm2\u003c/code\u003e if available or transition to more secure sandboxing solutions, as the \u003ccode\u003evm2\u003c/code\u003e project has reached end-of-life.\u003c/li\u003e\n\u003cli\u003eUpdate the \u003ccode\u003eDANGEROUS_BUILTINS\u003c/code\u003e configuration in the \u003ccode\u003evm2\u003c/code\u003e library to include \u003ccode\u003etest\u003c/code\u003e to block access to the \u003ccode\u003enode:test\u003c/code\u003e module at the source.\u003c/li\u003e\n\u003cli\u003eAudit existing configurations to identify and remove \u003ccode\u003enode:test\u003c/code\u003e from any \u003ccode\u003erequire.builtin\u003c/code\u003e allowlists.\u003c/li\u003e\n\u003cli\u003eIf test capabilities are required, implement a sandbox-local wrapper that does not expose the \u003ccode\u003erun()\u003c/code\u003e method, \u003ccode\u003eexecArgv\u003c/code\u003e, or any other host-process control parameters.\u003c/li\u003e\n\u003c/ol\u003e\n","date_modified":"2026-10-01T20:20:11Z","date_published":"2026-10-01T20:20:11Z","id":"https://feed.craftedsignal.io/briefs/2026-10-vm2-node-test-bypass/","summary":"The vm2 sandboxing library fails to properly secure the 'node:test' builtin module in Node.js 24+, allowing an attacker to escape the sandbox via a double-prefix require and execute arbitrary host code.","title":"vm2 NodeVM Sandbox Escape via node:test Builtin","url":"https://feed.craftedsignal.io/briefs/2026-10-vm2-node-test-bypass/"}],"language":"en","title":"CraftedSignal Threat Feed - Vm2 (\u003e= 3.9.6, \u003c= 3.11.5)","version":"https://jsonfeed.org/version/1.1"}