开源深处的隐性风险
现代数字基础设施的脆弱性,以及 xz-utils 事件留下的真正教训:我们依赖的不是代码,而是人。
2024 年 3 月,一个名叫 Jia Tan 的贡献者几乎成功地在 xz-utils 里植入后门。如果不是一位微软工程师在测 SSH 登录延迟时偶然发现异常,这个后门会随主流 Linux 发行版进入成千上万台服务器。
这件事已经被讨论过很多次,但大多数讨论停留在“供应链安全”这个词上。我想谈的是更不舒服的部分。
一个后门是怎么被养出来的
攻击者的耐心值得警惕。整个行动持续了两年多:
- 先提交无害的补丁,建立信任
- 再以“帮忙维护”的姿态接手停滞的项目
- 然后逐步替换测试数据、引入混淆的构建脚本
- 最后在发布包里加入恶意代码
每一步单独看都合理。没有哪一次提交会让人警觉。这才是关键——安全审计针对的是代码,而攻击发生在关系里。
维护者的困境
xz 的原作者 Lasse Collin 维护这个项目十几年,几乎没有报酬。当一个“热心贡献者”出现,愿意承担 issue 分类、CI 维护、版本发布这些枯燥工作时,任何一个疲惫的维护者都会心存感激。
这不是疏忽,这是结构性问题。我们整个行业把关键基础设施托付给了志愿者的业余时间,然后期待它像商业产品一样可靠。
开源不是“免费的软件”,它是“由少数人补贴的公共品”。当补贴者耗尽,公共品就开始腐烂。
具体能做什么
抱怨没有用,能做的是把抽象的风险变成具体的动作:
- 盘点依赖:跑一遍
npm ls --all或cargo tree,看看你有多少个间接依赖 - 锁定版本:提交 lockfile,并在 CI 里校验它没有被静默修改
- 关注维护者变更:项目突然换了主要维护者,是一个需要记录的事件
- 给依赖打钱:哪怕一个月 5 美元,也比零强
- 减少依赖:这是最有效的一条,也是最难的一条
# 看看你的项目到底依赖了多少东西
npm ls --all --parseable | wc -l
# 找出体积最大、更新最频繁的间接依赖
npx depcheck
一点不那么技术的话
xz 事件之后,我删掉了自己项目里一半的依赖。不是因为它们不安全,而是因为我意识到:我根本不知道它们在做什么。
一个只有 300 行、自己写清楚的模块,比一个 300 万行的框架更容易被信任。这不是要回到原始社会,而是要重新建立一种直觉——对“我引入了什么”保持敏感。