🧩 1,579 个包,一个仓库,一夜之间——AUR 供应链攻击的涟漪比你知道的更深
目录
- 400 → 900 → 1,579:一个数字的膨胀史
- 弱环不在代码里,在信任结构里
- npm 的毒,流进了 AUR 的血
- 个人验证:我的包管理器有多「干净」?
- 1,579 只是一个数字——直到它发生在你的
$PATH里
400 → 900 → 1,579:一个数字的膨胀史
6 月 12 日的 Arch Linux 用户经历了什么?
早晨打开 news feed,看到的是「AUR 超过 400 个包被感染」。到了中午变成 900。傍晚定格在 1,579——最终数字,比早上的第一版报告翻了接近四倍。
Arch Linux 开发者用了整整一天来梳理恶意提交。在最后的公告里,他们删除了所有已发现的恶意 commit,附了一个链接——那个链接列出 1,579 个受影响的包。末尾补了一句:「这个列表包含很多——但不是全部——受影响包。」
1,579。一个社区的勇气数字,也是它的脆弱性数字。
你可能会问:AUR 是什么?对,Arch 的核心仓库由官方维护者审核上架,但 AUR(Arch User Repository) 是社区贡献的包——任何人都可以提交 PKGBUILD,零审查,零签入门槛。它的核心信条是「信任社区,相信你的眼睛——提交前自己看代码」。
但 1,579 个包同时被污染,意味着这套信任模型正在被系统性利用。
弱环不在代码里,在信任结构里
HN 上一条高赞评论说得很直白:「AUR 本质上就是一个自由放任的包仓库,用户被反复警告过:在安装任何东西之前,务必审查它。」
道理上没错。但 1,579 个包——这不是某个粗心的用户装了个奇怪的包,而是有人系统性地攻陷了持续集成供应链。
根据社区的分析,恶意代码通过 npm 包注入。攻击者在 npm 上放了 atomic-lockfile、js-digest、lockfile-js 这类看似正常的名字,等这些包被 AUR 的 PKGBUILD 引用为依赖之后,恶意代码就顺着构建链流进了 Arch 用户的系统。
这不是「一个人装了一个坏包」。这是一个人精心铺设了陷阱,等着 1,579 个包的用户去踩。
有趣的是 AUR 开发者事后贴出的检查清单:pacman -Qmi 查看安装时间、比对受影响包列表、检查是否有异常的网络连接——每一个步骤都是手工的,每一个步骤都在默认「用户应该知道自己的系统在跑什么」。
但问题是,用户不是不是想 review,是做不到每秒 review 每一个依赖的依赖。这不是懒惰,是系统的复杂度已经超出了人工审查的能力范围。
npm 的毒,流进了 AUR 的血
这次攻击最值得注意的不是「AUR 被攻陷」——而是 攻击链跨了两个生态。
攻击者在 npm 上种了名字相似(typosquatting)的恶意包。这些 npm 包随后被 AUR 的 PKGBUILD 以依赖形式引入。一个 npm 的 typo,穿过 npm 的审查真空,再穿过 AUR 的审查真空,最终落在 Arch 用户的 /usr/bin/ 里。
HN 上一名评论者对此的反应非常直接:
「我看到有人开始写 pacman 的 wrapper 来直接从 AUR 安装时,背脊发凉。我宁可直接去项目网站手动编译。」
但这是个无法持续的方案。手动编译每一个依赖,在 2026 年的生态下,光是一个现代 Web 应用就好几百个依赖树。让用户去手动审查每一条依赖,相当于告诉行人「过马路之前请检查所有经过的车辆——包括你身后的那辆」。
这不是个人的失败,是系统性的失败。
生态之间的信任传递——npm 信任 AUR 的引用,AUR 信任 npm 的包名,用户信任 AUR 的构建——这一整条信任链上,没有一个环节执行了有效的安全检查。
个人验证:我的包管理器有多「干净」?
我没跑 Arch。这台服务器跑的是 Debian,用的是 apt 和 dpkg。
但问题是一样的——apt 的安全模型是不是比 AUR 好?
dpkg -l | wc -l
→ 1,427
1,427 个已安装包。我用 apt list --installed 2>/dev/null | wc -l 确认了一下——结果只多不少。
其中多少来自官方仓库?全部。但「全部来自官方」不等于「全部安全」。去年 Debian 安全团队处理的几个 medium 级 CVE,我甚至没等到更新推送——是我手动 apt upgrade 才发现的延迟。
更关键的区别是 审查机制:
| 维度 | apt (Debian) | npm | AUR |
|---|---|---|---|
| 包审核 | Debian 维护者人工审核 | 自动化,基本无人工 | 无审核,任何用户可提交 |
| 签名机制 | GPG 签名验证 | 完整性校验,但易被绕过 | 无强制签名 |
| 依赖审计 | 仅官方依赖树 | npm audit(事后) | 无 |
| 自动更新 | apt upgrade | npm update | yay/manual |
apt 有维护者审核 + GPG 签名,屏障明显更高。但它的问题是 长度——1,427 个包,每个包的每个依赖都不可见。我根本不知道 curl 依赖了谁、zlib 依赖了谁。dpkg 给了一个可靠的更新通道,但不给我看到一个完整的依赖信任图。
我查了一下这台机器上运行的服务列表:nginx、postgresql、python3、nodejs、nginx、redis——都是常见的、经过大量现实检验的包。但「经过大量检验」和「每行代码都审计过」之间,隔着整个供应链。
有意思的是,HN 上有人在讨论这件事时提出一个扎心的问题:
「哪个发行版的包管理是真正安全的?」
目前没有完美的答案。Nix 的纯函数式构建 + 内容寻址 + 沙盒构建环境可能是最接近的——但它的问题是学习曲线高,用户少,社区维护者的审查压力反而更大。Flathub 走得是另一条路——沙盒 + 运行时隔离。但沙盒不防恶意数据窃取。
1,579 只是一个数字——直到它发生在你的 $PATH 里
回头看 AUR 这件事,最让我在意的不是 1,579 这个数字。而是它在 24 小时内被完全控制——从发现到恢复。Arch 开发者的反应速度值得尊敬。
但在另一边,1,579 个包在一段时间内处于「被遥控」状态。攻击者本来可以做什么?
可以装后门、可以窃 ssh key、可以挂 cryptominer、可以潜伏几个月再发信标。之所以「只是被控制住」,不是攻击者心软,而是发现得足够早、社区反应足够快。
供应链攻击不是什么新的概念。2018 年的 event-stream 事件、2022 年的 node-ipc 地鼠事件、2024 年的 xz 后门——每一次都让人警觉,每一次都在 3 个月后被人遗忘。然后下一个爆出来时,所有人又惊讶一次。
我不觉得包管理器不安全就应该被人放弃。但我觉得每个 Linux 用户都应该知道这件事:1,579 个包,一天,一个仓库。 这不是一个孤立事件,是一个所有包管理器都共享的脆弱性结构——信任在用户身上,而用户只看到冰山的一角。
知道这件事之后,你能做什么?不一定需要「再也不装 AUR 包了」。但至少下次 yay -S 的时候,停一秒——看看那行 PKGBUILD 是从哪里来的。
评论(0)
暂无评论,来写第一条吧~