<!-- title: npm首个蠕虫复盘：你的令牌还安全吗 -->
<!-- domain: trending -->

# 一只沙虫爬进了500个npm包，海外社区吵翻了，国内却几乎没人讲透

## 导语

2025年9月中旬，海外安全圈和开发者社区被一个名字刷屏：**Shai-Hulud**——《沙丘》里的沙漠之虫，也是**npm生态史上第一个真正意义上的自复制蠕虫**。48小时内超过500个包被感染，数百万周下载量的包中招，紧接着11月又来了第二波。HN、r/javascript、r/LocalLLaMA 上围绕它的争吵持续了整整几个月，核心议题早就超出了事件本身：**当AI编程Agent人手一枚长期令牌时，JavaScript供应链还有救吗？**这篇文章把事件机制、社区三派观点、npm官方补救和一套你今天就能执行的令牌保卫清单一次讲清——这些细节讨论，国内中文社区至今很少有系统性拆解。

---

## 一、蠕虫是怎么爬进500个包的

先把机制讲透。根据 Wiz、Socket、Koi Security 等多家安全厂商在2025年9月的联合披露（细节以各厂商原文为准），Shai-Hulud 的攻击链大致如下：

1. **入口**：攻击者拿到了某些包维护者的 npm 发布令牌，率先污染了 `@ctrl/tinycolor` 这类周下载量以百万计的轮子包；
2. **引爆**：被投毒的版本带上了恶意 `postinstall` 脚本，任何开发者一执行 `npm install`，脚本就在本机静默运行；
3. **翻箱倒柜**：安装脚本会拉起 **TruffleHog**（一款本来就开源、常用于安全审计的密钥扫描器，GitHub 上 star 数以万计）扫描环境变量、`.npmrc`、CI 配置里的凭据；
4. **自我复制**：一旦扫到有效的 npm 令牌，蠕虫就用受害维护者自己的身份，向其名下**其他包**发布同样带毒的新版本——这就是“蠕虫”和普通投毒的本质区别，它会自己扩散；
5. **顺手掏家**：同时还往受害者的 GitHub 仓库里塞了一个 `shai-hulud-workflows` 定时 Action，持续外传仓库密钥；扫到的密钥甚至被 base64 编码后打包成新的 npm 包公开发布，等于把受害者的裤子挂在了公网上。

据 Wiz 当时的统计，受影响包在48小时内从约180个膨胀到500个以上。对国内开发者有一个容易被忽视的放大器：**国内镜像站（如 npmmirror）与官方源是分钟级同步的**，一个带毒版本发布后，你的内网 CI 可能在你看到任何新闻之前就已经把它装进生产构建了。

```mermaid
flowchart TD
    A["攻击者获取维护者 npm 令牌"] --> B["向热门工具包发布带 postinstall 钩子的新版本"]
    B --> C["开发者或 CI 执行 npm install"]
    C --> D["安装脚本静默运行 TruffleHog 扫描本机与 CI 配置"]
    D --> E{"扫到有效 npm 或 GitHub 凭据?"}
    E -- 是 --> F["用窃取的令牌向同一维护者名下其他包发布带毒版本"]
    F --> B
    E -- 否 --> G["将密钥 base64 编码打包成 payload.json 发布到 npm"]
    C --> H["向仓库注入 shai-hulud-workflows 定时 Action 持续外传"]
    F --> H
    G --> I["镜像站分钟级同步 感染面指数扩大"]
    H --> I
    J["防线1 令牌最小化与 OIDC 免令牌发布"] -.-> B
    K["防线2 CI 权限收敛与安装脚本白名单"] -.-> C
    L["防线3 蠕虫特征自查与全量轮换"] -.-> I
```

## 二、真正让海外炸锅的：上一场攻击里，AI Agent已经是帮凶了

如果 Shai-Hulud 只是“传统的”令牌窃取，社区还不至于吵成那样。真正的情绪引爆点在**一个月前**：2025年8月底，构建工具 Nx 遭遇代号 **s1ngularity** 的供应链攻击。据 Nx 官方事后复盘，攻击者污染了 nx 的 npm 包后，恶意脚本做的事和上面类似——扫凭据——但它多了一步骚操作：**调用本机已安装的 AI 命令行工具（报道中提及 Claude、Gemini 的 CLI）来帮助遍历和分析文件系统，更高效地定位凭据文件**。失窃的凭据还被直接发布到了受害者的公开 GitHub 仓库里。

这两个事件叠在一起，才有了海外社区真正焦虑的那个问题：**你的 AI Agent 正在拿着你权限最大的令牌干活**。本地跑的编码 Agent 能读全盘文件、能调 shell、CI 里的 Agent 能发布包——它们是凭据最集中的节点，也恰恰是最不设防的节点。攻击者不需要攻击 AI，只需要让 AI 帮他翻抽屉。

## 三、社区吵什么：三派观点整理

把 HN 和 Reddit 几个高热度帖子里的争论归纳一下，大致三派：

**激进派：“JS供应链已经死了。”** 这派认为 postinstall 钩子 + 长期令牌 + 单一管理员账号的组合烂到根上了，lockfile 根本防不住“包本身被投毒”——锁文件锁的是版本，不是恶意。他们主张彻底重构：默认禁用安装脚本、全面上签名与来源证明（provenance）、发布走短时效凭据。

**务实派：“别指望注册中心，管好自己的令牌。”** 这一派（在 r/LocalLLaMA 和 r/devops 里声音最大）指出：npm 官方再怎么加验证，也挡不住维护者自己把长期 classic token 写在 CI 环境变量里一放三年。真正的杠杆点在开发者侧——令牌最小作用域、短过期时间、发布通道与日常安装通道分离。

**AI担忧派：“爆炸半径是新问题。”** 这派不纠结 npm 本身，而是指出 s1ngularity 和 Shai-Hulud 共同暴露的新事实：组织里权限最大的凭据，越来越多地躺在你给 Agent 用的环境里。他们呼吁给 AI Agent 发**专用的、范围收窄的、可随时吊销的**凭据，而不是让它共用人类开发者的主令牌。

三派其实不冲突，叠加起来就是一份防御清单——也就是下面的行动指南。

## 四、npm官方的补救，和没完没了的第二波

事件之后 npm/GitHub 的动作值得专门记录，因为很多国内团队的 CI 至今还在用旧姿势：据 GitHub/npm 官方公告，2025年下半年 npm **分阶段吊销了长期有效的 classic token**，主推两条替代路线——**granular access token**（可限定包范围、可设过期）和 **trusted publishing**（基于 OIDC，CI 里根本不存令牌，发布时凭 GitHub Actions 的身份证明直接授权）。此外还收紧了新包发布的双因素验证要求（具体时间线以官方文档为准，本文不引具体日期）。

但故事没完。据 Wiz 等厂商在2025年11月前后披露，Shai-Hulud 出现了第二波变体，媒体报道中称为"Shai-Hulud: The Second Coming"，影响包数量据称达数百个，一些知名 SaaS 厂商相关的 npm 组织被波及。这说明：**治理补丁落地之前，猎手不会停手**。

## 五、信息差总结

| 维度 | 你可能知道的 | 别人已经在讨论的 |
|------|------------|----------------|
| 事件定性 | “npm又中招了，而已” | 史上第一个npm自复制蠕虫，会借维护者令牌自我扩散 |
| 攻击工具 | 黑客自研恶意代码 | 直接复用开源审计工具 TruffleHog，白帽工具变黑产凶器 |
| AI的角色 | AI只是被攻击对象 | Nx事件中AI CLI已被攻击者调用来翻找凭据 |
| 防护重心 | lockfile、npm audit | 令牌生命周期管理 + OIDC免令牌发布 + Agent专用凭据 |
| 国内盲区 | 以为镜像站是安全的 | 镜像分钟级同步，带毒版本进内网CI可能快于新闻 |
| 应急能力 | 中招后再说 | 社区已有成熟自查特征清单，分钟级可完成排查 |

## 六、行动指南：今天就能做的七步

1. **查存量令牌**：登录 npmjs.com → Access Tokens，凡是没有过期时间和包范围限制的 classic token，全部吊销重建为 granular token；
2. **发布改用 trusted publishing**：npm 官方文档有完整指引（见参考来源），GitHub Actions 里只需声明 `permissions: id-token: write`，令牌从此不落盘；
3. **CI 权限收敛**：所有 workflow 默认 `permissions: contents: read`，按需单独放开，杜绝一把梭的 `GITHUB_TOKEN`；
4. **自查蠕虫特征**：全仓搜索三个关键词——`shai-hulud-workflows`、`Shai-Hulud Research`（被投毒包的描述字段）、来源不明的 `payload.json`；命中任何一条，立即在 npm 和 GitHub 侧全量轮换凭据；
5. **给 AI Agent 单独开户**：本地和 CI 里的编码 Agent 不要复用你的主令牌，用独立账号 + 最小范围 + 短时效，出事可一键吊销；
6. **安装脚本加白名单**：私有源/代理层拦截陌生新版本，对带 `postinstall` 的冷门新包执行发布后观察期（24-72小时）再进内网；
7. **订阅两份情报**：Socket 博客和 Wiz 博客的供应链条目，出现 npm 相关应急通报时，把同步间隔当作战时钟来用。

一句话收尾：Shai-Hulud 最大的遗产不是那500个包，而是让整个行业看清了一件事——**在 Agent 时代，凭据管理就是新的安全边界**。你的 `.npmrc` 里那行旧令牌，才是整场论战真正的靶心。

## 参考来源

> 注：以下给出官方入口页；深层文章请按文中关键词（如 "Shai-Hulud"）在站内检索直达，本文未直接核验深层链接，故不虚构具体文章 URL。

1. Wiz 安全研究博客（Shai-Hulud 事件完整技术拆解）：https://www.wiz.io/blog
2. Socket 供应链安全博客（恶意包实时监测与事件通报）：https://socket.dev/blog
3. npm 官方文档 · Trusted Publishing（OIDC 免令牌发布）：https://docs.npmjs.com/trusted-publishers
4. npm 官方文档 · Access Tokens（granular token 说明）：https://docs.npmjs.com/about-access-tokens
5. TruffleHog 开源项目（事件中被滥用与本篇提到的自查思路）：https://github.com/trufflesecurity/trufflehog

---
> 本文由「51学通信」技术团队出品。51学通信由通信行业18年老兵**爱卫生**（微信ID: gprshome201101）维护。
> 聚焦5G/6G核心网、3GPP标准、AI工具实战。知识星球「51学通信」提供深度技术答疑和行业洞察。

> [!tip] 51学通信知识星球
> **星主：爱卫生**（微信：gprshome201101）——公众号「51学通信」创办者，19 年通信行业运维与讲师经验，著有《GPRS网络信令实例详解》《EPC原理与实践》《5G核心网原理与实践》三本纸质书（各大电商平台有售）。
> **星球定位**：深耕 5G 核心网、IMS、NFV/AI、云原生等 ICT 领域，主打运维岗位与信令分析。
> **当前规模**：5200 篇主题 / 990 个回答，198 元/年。
> **加入福利**：加入星球后请加爱卫生微信，拉您进知识星球年度陪伴与答疑群——不限量回复您的各种问题，另有群内分享。
> **AI 加持**：51学通信知识星球已作为 skill 接入 WorkBuddy，使用 deepseek-4-flash 在海量星球帖子中精准找贴、找视频、找 FAQ 和案例，做总结、找文档和 PPT 等场景全覆盖。

![51学通信知识星球海报-扫码加入](https://wiki.500nian.com/images/zhixingqiu_qrcode.png)
