OC
恶意 Rust 库 arrayref 在构建时运行负载:编译器也成了攻击入口
科技 · 2026-08-21 · 开发者工具 · 阅读 18

恶意 Rust 库 arrayref 在构建时运行负载:编译器也成了攻击入口

据 SafeDep 的分析 报道,Rust crate arrayref 的 0.3.10 版本被发现带入恶意依赖 proc-macro1。真正执行下载和运行负载的不是 arrayref 的宏代码,而是依赖包里的 build.rs。只要项目重新解析依赖并完成编译,恶意代码就可能在程序运行前执行。

作者 林岚 林岚

据 SafeDep 的分析 报道,Rust crate arrayref 的 0.3.10 版本被发现带入恶意依赖 proc-macro1。真正执行下载和运行负载的不是 arrayref 的宏代码,而是依赖包里的 build.rs。只要项目重新解析依赖并完成编译,恶意代码就可能在程序运行前执行。

这起事件最值得开发者警惕的地方,是它没有依赖一个看起来很可疑的库名。攻击者使用了接近真实 proc-macro2 的拼写,把正常源码复制进 proc-macro1,再把恶意逻辑放在构建脚本里。代码能正常编译,反而让“编译成功”变成了掩护。

根据分析,arrayref 0.3.10 新增了对 proc-macro1 1.0.107 的依赖。后者的构建脚本会拼出远程地址,下载与系统架构对应的二进制文件,并在 Linux、macOS 或 Windows 上启动。它还通过放宽 TLS 证书校验,降低了直接使用 IP 地址下载负载的门槛。

攻击传播利用了 Cargo 依赖解析的一个现实细节:当旧版本被撤回后,开发者可能会被提示升级到唯一尚未被撤回的新版本。如果这个新版本正好携带恶意依赖,版本更新提示就不再只是维护信息,而成了诱导路径。arrayref 又经常作为 GUI 和图形库的传递依赖出现,使用者未必在自己的 Cargo.toml 里直接写过它。

这不是 Rust 特有的“语言不安全”问题。Cargo 会构建声明的依赖,而构建脚本本来就有下载文件、访问环境变量和执行外部命令的能力。Rust 的类型系统可以帮助防止运行时内存错误,却不能替开发者判断一个依赖的维护者身份、版本变更和构建期行为是否可信。

依赖解析、build.rs 与远程负载之间的执行链

关键事实

  • 受影响版本:arrayref 0.3.10,以及被报告为冒名或恶意的 proc-macro1 版本。
  • 攻击时机:构建期,不需要等最终程序启动。
  • 传播方式:依赖版本更新、传递依赖和被冒用的维护者身份。
  • 处置情况:相关恶意版本已从 crates.io 移除;是否实际执行过负载,仍需结合本地构建日志和网络日志判断。

OC 判断

依赖安全的检查单位不能只停留在“这个库有没有漏洞”。对 Rust、Node.js、Python 等生态而言,真正需要审计的是一次构建会拉下哪些包、运行哪些脚本、连接哪些地址。锁文件只能固定版本,不能自动证明版本没有被接管。

为什么重要

  • 对开发者:重新生成锁文件或清理缓存后构建,都可能重新触发依赖解析。
  • 对团队:CI 应记录依赖来源、构建脚本行为和出站网络,而不是只保存编译结果。
  • 对生态:热门传递依赖的维护者账户和发布权限,已经是基础设施安全的一部分。

参考来源

相关阅读

基于标题、摘要和正文内容自动匹配。

更多科技

评论

围绕这篇文章补充信息、提出问题或分享观察。

0
暂无评论。

发表评论

继续看看 OC 用户围绕这个话题说了什么、做了什么。

相关帖子

更多

做 AI 语音产品时,授权、撤回和审计日志应该怎么落地?

<p>最近看到越来越多关于声音授权的讨论。对开发者来说,真正麻烦的往往不是“模型能不能模仿”,而是授权如何进入系统、生成结果如何追溯,以及授权撤回后该怎么办。</p> <p>我们在做 FlowSpeech 时也碰到过类似问题。我的体会是,不要把“用户勾选过同意”当成一个布尔字段,而应该把它做成一组可以审计的业务对象。</p> <h2>1. 把声音资产和授权分开</h2> <p>声音文件只描述技术属性,例如哈希、上传者、存储位置和创建时间。授权记录则至少要包含授权主体、用途范围、地域、有效期、来源证据和当前状态。这样同一份声音用于个人试听、商业广告、公开播客时,可以绑定不同的授权,而不是共用一个模糊的 consent=true。</p> <h2>2. 每次生成都保存授权快照</h2> <p>生成任务不要只引用当前授权 ID。授权内容以后可能变更,如果任务只查最新状态,历史结果就无法解释。更稳妥的做法是在任务创建时保存授权版本、文本哈希、声音版本、模型版本和操作者。生成出的音频再记录 artifact_id,并反向关联任务。</p> <p>我会把最小链路设计成:</p> <ol> <li>voice_asset:原始声音及版本;</li> <li>consent_grant:授权范围与证据;</li> <li>generation_job:请求参数和授权快照;</li> <li>audio_artifact:输出文件、校验值和公开状态;</li> <li>audit_event:谁在什么时候创建、下载、公开或撤回了内容。</li> </ol> <h2>3. 撤回不是简单删除一行</h2> <p>授权撤回后,系统至少要阻止新任务,并把相关公开音频进入下架队列。已经交付给客户的文件是否能删除,要按照合同和产品能力区分,不能在界面上承诺技术上做不到的“全球删除”。更现实的状态机是 active、suspended、revoked、expired,并明确每个状态允许哪些动作。</p> <h2>4. 对外展示也要可验证</h2> <p>除了后台日志,公开音频最好带上来源标记或可查询的生成记录。水印不是万能方案,但“可识别的音频 + 可验证的元数据 + 清晰的举报入口”组合起来,比一句“AI 生成”更有用。</p> <p>我们现在做的 <a href="https://flowspeech.io/zh">FlowSpeech</a> 主要解决上下文感知、情绪和停顿控制。越往产品化走,越觉得声音效果只是前半程,权限边界和可追溯性才决定这类工具能不能长期使用。</p> <p>大家在实际项目里会把授权证据放在业务数据库、对象存储,还是单独的审计系统?如果授权撤回,你们通常怎么处理已经生成并交付的音频?</p>

FlowSpeech 0 1

你为什么不移民?

<p>我是一定要移了,在这里连正常呼吸都不行了。以前正常呼吸指的是言论自由,现在是生物学意义的正常呼吸问题了。</p> <p>你为什么不移民?</p>

tinyfool 741 48