npm 包被投毒:一次 postinstall 能带走多少凭证

2026 年 10 月,tensorlake 的 0.5.144 被植入 Shai-Hulud 蠕虫,目标是 npm、GitHub、云厂商与 AI 服务的凭证。供应链攻击的门槛,已经低到一次账号失守。

装一个依赖,就等于把发布者的账号安全一起装进来。10 月 7 日,TypeScript SDK tensorlake 的 0.5.144 被确认携带 Shai-Hulud 凭证窃取蠕虫;0.5.143 及更早的版本被报告为干净。

时间线

StepSecurity 的复盘给出了相当精确的坐标:首个恶意提交在 2026-10-07 01:20 UTC 进入 tensorlakeai/tensorlake 的 main 分支,用的是一位维护者的名义。随后数小时内又跟了 7 次提交,逐步调整载荷,并往 package.json 里加了一条 preinstall 指令。

值得注意的是节奏:不是一次注入就收手,而是有人盯着结果改。这更像一次持续作业,而不是脚本撞库。

载荷盯上了什么

被窃取的目标列表基本覆盖了现代开发者的全部家当:

  • npm 与 GitHub 令牌
  • 云厂商密钥
  • SSH 密钥
  • Vault 与 Kubernetes 凭证
  • 浏览器登录信息
  • AI 工具配置

其中「AI 工具配置」这一项值得单独看。过去这类蠕虫只关心 CI 与云,现在它开始关心你本机上那些能直接调用大模型的 key——那东西没有配额告警,也没有审计日志,被拿走很久都不会有人发现。

为什么 provenance 挡不住

npm provenance 只能证明「这个包是从哪个仓库、哪个提交构建出来的」,它证明的是构建来源,不是源码内容。

这次的入口恰恰是维护者账号本身。构建链条上每一环都是真的:真的仓库、真的提交、真的 CI。供应链攻击早就不在「伪造来源」这一层打了,它在「来源本身被借用」这一层。

provenance 解决的是「这包是谁建的」,不解决「建它的人还是不是原来那个人」。

清理时最容易踩的坑

一个反直觉的细节:载荷里带了令牌监视器,如果先吊销被盗的 GitHub 令牌、再移除监视器,监视器可能直接清空 home 目录。

也就是说,标准应急动作(第一时间吊销凭证)在这里反而会触发数据损失。这不是让人别吊销,而是说明一件事:清理顺序本身是需要情报的,不能只靠肌肉记忆。

我的判断

对个人项目,我不打算上什么复杂的供应链防御。真正能落地的只有三条:

  1. 锁文件进版本库,并且认真看 diff——package-lock.json 里多出一个 preinstall 是能被看见的;
  2. 别在开发机上放长期有效的云凭证,能用短期令牌就用短期;
  3. 装新依赖时,npm install --ignore-scripts 至少能挡住这一类。

第三条有个明确的代价:有些包真的需要构建步骤,忽略脚本会装不上。但「装不上」是个能立刻发现的问题,「装上了但被偷了」不是。

← 返回文章列表

评论

…