news 2026/10/4 3:25:49

脚本进了沙箱,模块却在宿主执行:vm2 CLI 漏洞与默认配置审计

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
脚本进了沙箱,模块却在宿主执行:vm2 CLI 漏洞与默认配置审计

脚本进了沙箱,模块却在宿主执行:vm2 CLI 漏洞与默认配置审计

一、先把时间线和影响范围说清

GitHub 已审核记录列出:CVE-2026-92950影响 npm 包vm2 <=3.11.6,最低修复版本为3.11.7。项目于2026-08-24发布相关公告,记录于2026-10-01进入 GitHub Advisory Database 并完成审核。因此本篇是新收录带来的工程复盘,不是十月刚发生的攻击通报。

3.11.7 发布说明与修复提交相互印证:CLI 增加模块根目录限制,并将允许加载的模块置于 sandbox 上下文。发布页显示该版本于8 月 24 日发布。

这里的特定入口是运行外部脚本的 vm2 CLI。不能仅凭依赖树出现 vm2,就断言业务已经被攻击;也不能因为业务没有调用 CLI,就忽略自己构造 NodeVM 时是否采用了相同宽松配置。

二、技术原理:导出值的包装发生得太晚

1. 脚本入口和模块入口是两扇门

从工程角度看,脚本平台至少需要约束两个入口:最初脚本的执行器,以及脚本请求依赖时使用的加载器。前者把代码放进受限环境,不代表后者也继承限制。

公告描述的默认组合中,外部加载被打开,但没有设置模块根目录,执行上下文使用宿主。模块加载不仅返回一个对象,还会运行模块初始化代码。因此,在返回值外面增加只读包装,不能撤销初始化阶段已经发生的副作用。来源:漏洞记录

这是一类很有迁移价值的审计模式:不要只问“返回给不可信代码的对象是否只读”,还要问“为了获得这个对象,系统先执行了什么”。同样的分析方法可以用于模板扩展、插件发现和动态配置加载。

2. 路径限制和执行上下文不能互相替代

路径边界回答“能加载哪些文件”;上下文边界回答“被加载代码拥有什么权限”。允许的目录中也可能放着不可信文件,只限制目录未必安全。反过来,即便执行上下文受到限制,也不应无理由开放整个宿主文件树。

设计状态仍需回答的问题
路径受限、宿主执行目录里的代码是否全部值得授予宿主能力?
路径开放、受限执行不应读取的代码或数据是否仍可被发现?
路径和上下文同时限制导入能力、资源上限与跨任务状态是否受控?

表格是设计分析,不是对每一种 vm2 配置的完整漏洞判定。

3. CLI 修复不等于替应用重新设计权限

官方发布说明保留了一个重要边界:对于嵌入者使用外部加载、未设根目录、且采用宿主上下文的情形,本次版本采用警告提示,并非全面改成构造失败。兼容性选择不应被理解成安全保证。来源:3.11.7 升级说明

因此升级后仍要检查应用自己的new NodeVM(...)和封装工具。把安全责任完全交给包版本号,会漏掉由应用主动授予的高权限。

三、无害实验:只计算策略,不运行模块

下面模型使用虚拟路径字符串,不读取磁盘,不导入 JavaScript,不启动宿主进程。它说明两项检查为何需要同时存在,不是生产沙箱实现。

frompathlibimportPurePosixPathdefpolicy_allows(module,root,context):ifrootisNoneorcontext!="sandbox":returnFalsepath=PurePosixPath(module)base=PurePosixPath(root)ifnotpath.is_absolute()ornotbase.is_absolute():returnFalseif".."inpath.partsor".."inbase.parts:returnFalsereturnpath==baseorbaseinpath.parents cases=[("/job/helper.js","/job","sandbox",True),("/job/helper.js","/job","host",False),("/job/helper.js",None,"sandbox",False),("/other/helper.js","/job","sandbox",False),("/job2/helper.js","/job","sandbox",False),("/job/../other.js","/job","sandbox",False),]formodule,root,context,expectedincases:assertpolicy_allows(module,root,context)isexpectedprint("6 policy checks passed; no module executed")

这个模型故意拒绝父目录片段,并按路径段比较,避免字符串前缀把相邻目录当成子目录。但它没有处理真实文件系统中的符号链接、竞态、硬链接及平台差异。不能直接复制为生产路径授权组件。

实验价值在于测试结构:保持模块路径不变,只切换上下文;保持上下文不变,只切换根目录。这样失败原因可定位,避免一组大而杂的攻击样本掩盖真正的安全不变量。

四、检测思路:检查部署入口,不只扫描 package.json

建议先建立运行入口清单:全局安装的 CLI、项目本地依赖、自研包装命令、长驻脚本服务和临时 CI 容器应分别盘点。锁文件只能说明一个构建输入,未必覆盖全局工具或旧镜像。

随后审查调用点:是否允许外部依赖,模块根目录由谁指定,上下文来自默认值还是显式配置,配置是否能被脚本作者或仓库内容覆盖。对于封装层,检查最终合并后的配置,而不是某个看起来安全的默认对象。

最后检查环境权限。即使脚本平台只用于“格式转换”,它运行的账号可能持有发布凭据或服务访问权。这属于部署风险推断,需要用挂载、环境变量和网络策略证据验证,不能直接写成该漏洞已经导致密钥泄露。

五、修复与防护建议

立即处理

升级 CLI 至包含此修复的版本,最低为3.11.7。同时检查全局安装和运行镜像,避免只升级开发依赖。对外部脚本,在验证隔离之前暂停高权限执行。

回归验证

为 CLI 和嵌入 API 分别建立测试。CLI 应验证模块加载限制;API 应验证应用声明的允许目录、上下文和能力列表。测试结果中应记录入口、版本、Node.js 版本及最终配置,使“已验证安全”的结论有清晰适用范围。

不要把一次正常脚本成功作为全部回归。至少需要验证相邻目录、目录外模块、拒绝后的清理行为以及并发任务之间的状态隔离。真实安全测试应在一次性、无生产凭据的环境执行。

平台长期治理

对真正不可信的代码,建立独立进程或更强系统隔离,限制网络、文件挂载和资源额度。语言级限制与操作系统限制承担不同职责;进程超时也需要由外部监督者实施,不能只依赖被执行代码所在环境自行结束。

这里不承诺某种容器配置绝对安全。目标是让单个库的失误不再直接获得整个宿主身份的能力,并能在失败后销毁任务环境。

六、总结

最容易被忽略的沙箱入口,往往不是最初执行脚本的那一行,而是后来加载模块的那一行。审计应该沿着“代码由谁加载、在哪里初始化、继承哪些权限”继续追踪。版本升级关闭了已知缺陷,应用仍需对自己授予的能力负责。d确认在野利用,未把公开验证等同于现实入侵。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/4 3:25:12

长沙曾食坊小吃培训的米线螺蛳粉:酸辣底味怎么调

本篇要点&#xff1a; 1. 酸笋处理与气味控制&#xff1b;2. 汤底层次与辣酸平衡&#xff1b;3. 配菜下锅顺序。螺蛳粉的门槛不在粉&#xff0c;而在那股"闻着冲、吃着香"的底味怎么调稳。本文补的是米线螺蛳粉在酸辣结构上的那一层&#xff1a;从酸笋怎么处理、汤底…

作者头像 李华
网站建设 2026/10/4 3:25:05

长沙曾食坊小吃培训的张家界学员:景区餐饮选品怎么定

本篇要点&#xff1a;- 景区客流结构&#xff1a;团队客与散客、淡旺季落差极大&#xff1b;- 菜单不宜过宽&#xff1a;快出餐与便携优先&#xff1b;- 租金与位置换手率&#xff1a;选品要匹配摊位流动成本。张家界做景区餐饮&#xff0c;客流和城区完全不是一个逻辑&#xf…

作者头像 李华
网站建设 2026/10/4 3:23:24

SQL Server数据类型详解:存储原理、精度陷阱与建表选型

很多朋友一开始接触 SQL Server 数据类型的时候&#xff0c;都觉得这有什么好学的&#xff1f;不就是 int、varchar、datetime 那几个吗&#xff1f;我早前也是这样想的&#xff0c;直到有一天帮同事排查一个报表对账差异&#xff1a;订单表的金额字段当年图省事用了 float&…

作者头像 李华
网站建设 2026/10/4 3:23:16

Java毕设安全牌:Spring Boot学生管理系统从设计到答辩

1. 选题价值&#xff1a;学生管理系统为什么是毕设的"安全牌"做毕设选题时&#xff0c;我见过太多人纠结来纠结去&#xff0c;最后选了一个自己都说不清楚要做什么的方向。相比那些花哨的推荐算法、大数据分析&#xff0c;学生管理系统这种经典CRUD项目&#xff0c;反…

作者头像 李华
网站建设 2026/10/4 3:20:49

插件加载失败排查指南:从IAR、MusicFree到Web Boot

我最近连续被几个和plugins相关的报错和提问刷屏&#xff1a;failed to load plugins web boot: 2 entries did not activate linxin666/dsh-p、harness failed to load plugins、iar plugins 是干什么的&#xff0c;还有musicfree plugins。这几个问题表面上看毫不相关——一个…

作者头像 李华
网站建设 2026/10/4 3:20:48

插件加载失败排查指南:从failed to load plugins到web boot全链路解析

凌晨三点&#xff0c;我盯着终端里那行红字发呆&#xff1a;failed to load plugins web boot: 2 entries did not activate。这不是我第一次遇到插件加载失败&#xff0c;但每次看到“did not activate”这种半吊子英文&#xff0c;还是会头疼——它既没说哪个插件挂了&#x…

作者头像 李华