Rust 构建脚本沙箱
开发者首次构建新 Rust 依赖时,按 crate 隔离构建脚本,越界读写或联网必须先获准。
Rust 开发者新增依赖或更新锁文件后,最危险的一步往往发生在第一次执行 cargo build:某个 crate 的 build.rs 会在编译阶段拿到开发机权限。这个命令行包装器在构建前列出新增或变更的构建脚本,并为每个脚本单独启动沙箱,而不是让所有依赖共享同一套权限。
沙箱默认允许读取该依赖源码、写入目标构建目录。脚本试图读取 SSH 密钥、扫描家目录、启动子进程或联网时,构建会停在该动作之前。终端里直接显示 crate 名称、依赖版本、目标文件或域名,以及触发调用的脚本行。开发者可单次放行,也可拒绝并保留失败现场供团队查看。
已经核准的权限会随 Cargo.lock 一起提交,例如某个代码生成依赖可访问指定的编译器或下载固定域名。依赖版本一变,旧授权立即失效,CI 会重新跑一遍隔离构建,并把新增的权限请求标成合并阻塞项。安全同事不必从海量构建日志里猜谁做了什么。
首个版本专注 Cargo、build.rs 和常见的本地与 CI 环境,先把文件、网络和进程权限管住。它不承诺审计编译产物运行后的全部行为,也不替代依赖源码审查;目标是在脚本第一次摸到开发机之前,让团队有一次看见和决定的机会。
为什么是现在
8 月 20 日,恶意 arrayref 版本通过依赖的 build.rs 在编译时下载并运行载荷。S1 截至 8 月 21 日,该事件在 Hacker News 排名第 5,获 378 points 和 355 条评论,开发者更可能重新检查首次构建对本机权限的默认放行。S2
目标用户
核心用户是维护 Rust 服务或大型工作区的开发者。触发时刻是新增依赖、更新 Cargo.lock,或接手陌生分支后的首次构建。此时依赖代码尚未获得团队信任,build.rs 却即将取得开发机权限。负责 CI 与供应链安全的人也适用,因为他们需要审查新增能力,而非翻查完整构建日志。
最小切入点
先支持 Linux 本地环境与常见 CI。读取 Cargo.lock,并用 cargo metadata 建立依赖图。对比基线后,仅标出新增版本及 custom-build 目标。包装器在 Cargo 子进程下追踪 exec,并识别每个 build-script 进程。文件与进程动作交给 syscall broker 拦截,联网经受控代理按域名放行。策略以 crate 名、精确版本和动作范围为键,提交到仓库。Cargo 官方也在探索限制构建脚本的文件与网络权限。S3 行号先借助调试信息还原;无法稳定定位时,明确降级到脚本路径和调用栈。
以小博大
第一批用户可从 Rust 安全团队、基础设施团队和大型工作区维护者中寻找。发布一个可复现的恶意 build.rs 演示仓库,让用户直接看到读取密钥与联网请求在执行前被截停。再提供 GitHub Actions 模板,把锁文件新增权限变成拉取请求检查。围绕真实 crate 维护兼容配方,能形成持续可搜索的技术内容。
竞品与缝隙
怎么赚钱
按活跃开发者席位订阅,开源项目与个人本地使用免费。付费版提供私有策略仓库、CI 合并阻塞、审批记录和团队权限模板。
反方视角
大量正常 build.rs 会调用编译器、链接器、Python 或系统探测命令,默认收紧后容易频繁中断构建。每次误拦都要开发者判断路径和域名,审批疲劳会促使团队放宽规则。按域名放行还要处理 DNS、重定向和代理兼容,离线构建也可能暴露不同路径。源码行归因受优化、库调用和缺失调试信息影响,无法保证每次准确。Linux、macOS 与 Windows 的隔离能力差异很大,策略可移植性会持续增加维护成本。若安装后先出现兼容故障,团队可能直接回到容器或人工审查。