<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Vm2 (3.10.5) — CraftedSignal Threat Feed</title><link>https://feed.craftedsignal.io/products/vm2-3.10.5/</link><description>Trending threats, MITRE ATT&amp;CK coverage, and detection metadata — refreshed continuously.</description><generator>Hugo</generator><language>en</language><managingEditor>hello@craftedsignal.io</managingEditor><webMaster>hello@craftedsignal.io</webMaster><lastBuildDate>Wed, 03 Jan 2024 12:00:00 +0000</lastBuildDate><atom:link href="https://feed.craftedsignal.io/products/vm2-3.10.5/feed.xml" rel="self" type="application/rss+xml"/><item><title>vm2 NodeVM require.root Bypass via Symlink Traversal</title><link>https://feed.craftedsignal.io/briefs/2024-01-03-vm2-symlink-bypass/</link><pubDate>Wed, 03 Jan 2024 12:00:00 +0000</pubDate><author>hello@craftedsignal.io</author><guid isPermaLink="true">https://feed.craftedsignal.io/briefs/2024-01-03-vm2-symlink-bypass/</guid><description>A vulnerability exists in vm2 version 3.10.5 where NodeVM's `require.root` path restriction can be bypassed using filesystem symlinks, allowing sandboxed code to load modules from outside the allowed root directory in host context, leading to remote code execution.</description><content:encoded><![CDATA[<p>The vm2 library, a popular Node.js sandbox, is vulnerable to a symlink bypass in version 3.10.5. This flaw allows sandboxed code to escape the intended restrictions imposed by the <code>require.root</code> option. The vulnerability arises because the path validation performed by <code>isPathAllowed</code> uses <code>path.resolve()</code>, which does not dereference symlinks. In contrast, Node.js&rsquo;s native <code>require()</code> function, used for module loading, does follow symlinks. This discrepancy allows an attacker to create a symlink within the allowed root directory that points to a location outside the root, effectively bypassing the sandbox and enabling the loading of arbitrary host-realm modules. This can lead to remote code execution on the host system. The presence of symlinks is common in environments using pnpm, npm workspaces, or npm link.</p>
<h2 id="attack-chain">Attack Chain</h2>
<ol>
<li>Host application creates a <code>NodeVM</code> instance with <code>require.root</code> set to a specific directory (e.g., <code>/tmp/root</code>) and <code>require.context</code> set to <code>host</code>.</li>
<li>A symlink is created within the <code>require.root</code> directory (e.g., <code>/tmp/root/node_modules/safe</code>) that points to a location outside the root directory (e.g., <code>/outside/root/vm2/</code>). This symlink can be created using tools like pnpm or npm link.</li>
<li>Sandboxed code within the <code>NodeVM</code> calls <code>require('safe')</code>, intending to load a module from within the allowed root.</li>
<li>The <code>DefaultResolver.resolveFull()</code> function resolves the module path to <code>/tmp/root/node_modules/safe/index.js</code>.</li>
<li>The <code>isPathAllowed()</code> function checks if the resolved path starts with the <code>require.root</code> directory, which passes because the symlink is not yet resolved.</li>
<li>The <code>loadJS()</code> function detects that <code>context</code> is set to <code>host</code> and calls <code>this.hostRequire(filename)</code>.</li>
<li>Node.js&rsquo;s native <code>require()</code> function follows the symlink, loading the module from the actual location outside the root directory, <code>/outside/root/vm2/index.js</code>.</li>
<li>The module from outside the intended sandbox is executed in the host realm, potentially granting the attacker the ability to execute arbitrary commands on the host system.</li>
</ol>
<h2 id="impact">Impact</h2>
<p>Successful exploitation allows untrusted sandboxed code to escape the vm2 sandbox, achieving remote code execution on the host system. An attacker can bypass the <code>require.root</code> restriction, a primary defense mechanism, and load arbitrary modules from the host realm. This is particularly impactful in environments that use pnpm, npm workspaces, or <code>npm link</code>, as these tools frequently create symlinks, making the vulnerability more readily exploitable. The vulnerability can lead to complete compromise of the host system.</p>
<h2 id="recommendation">Recommendation</h2>
<ul>
<li>Apply the recommended remediation by dereferencing symlinks with <code>fs.realpathSync</code> before path validation in <code>lib/filesystem.js</code> and <code>lib/resolver-compat.js</code> as outlined in the advisory to prevent the bypass.</li>
<li>Deploy the &ldquo;vm2 Sandbox Escape via Suspicious Host Require&rdquo; Sigma rule to detect attempts to load modules from outside the intended sandbox via symlinks.</li>
<li>Upgrade to a patched version of vm2 that includes the fix for CVE-2026-43998.</li>
</ul>
]]></content:encoded><category domain="severity">high</category><category domain="type">advisory</category><category>sandbox-escape</category><category>remote-code-execution</category><category>symlink</category></item></channel></rss>