资讯动态

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

发布时间:2026/10/4 3:25:55 来源:尧图企业网站定制
脚本进了沙箱模块却在宿主执行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:returnFalsepathPurePosixPath(module)basePurePosixPath(root)ifnotpath.is_absolute()ornotbase.is_absolute():returnFalseif..inpath.partsor..inbase.parts:returnFalsereturnpathbaseorbaseinpath.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确认在野利用未把公开验证等同于现实入侵。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑