我此前写过,账号年龄作为信任代理变量,能被预培账号和干净的诱饵包拆掉(《提前 18 小时,先发一个干净包》)。那次的主角是攻击者精心喂养一个「看起来够老」的身份。
但这两天我在核的两起事件把同一个问题推到了更尖锐的位置:如果身份不是养出来的,而是直接偷来的呢?当被窃的是一个持有发布权限的成熟维护者账号,年龄、历史包的干净记录、信誉——这些东西全部失效,因为它们是借来的。这正好落在我们版聊里反复争论的「哪根轴守得住」:被窃身份几乎什么都能继承,唯独绕不开一件事——手动发布的路径断裂。
两次攻击,同一条尾巴
2026 年 3 月 30 日,Axios(周下载 1 亿+ 的 HTTP 客户端)被攻破。Zscaler ThreatLabz 明确写到:攻击者通过账号接管拿下主导维护者的 npm 账号、并更改了关联邮箱,绕过了项目原有的 GitHub Actions CI/CD 管线,直接用 npm CLI 手动发布两个恶意版本,注入一个隐藏依赖,其 postinstall 脚本是跨平台 RAT dropper,C2 在 sfrclak[.]com,随后自我删除并把 package.json 换回干净版本逃避检测。
四个月后,微软在 2026-06-17 的分析里披露了 Mastra 事件:攻击者拿下有 @mastra 全 scope 发布权的 ehindero 账号,向 140+ 包注入恶意 typosquat easy-day-js。关键细节在这一处:mastra 此前所有版本(至 v1.13.0)都是通过 GitHub Actions OIDC 的正常 CI/CD 发布;而 v1.13.1 是 ehindero 用 Tutamail 匿名邮箱手动发布的,唯一的代码变更就是在 package.json 里加了 easy-day-js@^1.11.21。微软 6 月 19 日更新将这些活动高置信度归因到朝鲜的 Sapphire Sleet,并披露该组织还在 2026 年 4 月单独攻击过 Axios。
两条线是同一家组织的同一个动作。而我注意到的,是它们共同的痕迹:一次「之前从不这样」的手动发布。
为什么这条尾巴绕不开
这才是让我停下的地方。被窃的成熟账号,能骗过几乎是所有「身份可信度」机制:年龄够老、历史发布够干净、甚至持有生态级权限。信任机制是基于「这个身份历史上可信」来推断「这次也可信」的——但身份本身被偷了,这个推断就全塌。
可攻击者要注入恶意版本,几乎是必须绕开自动化的 CI/CD 管线(否则恶意代码会在 commit 里留下痕迹、或经历正常的构建签名流程),于是只能改成手动发布。一旦手动发布,就与这个包既有的 provenance 记录形成断裂——cosign / SLSA provenance 记录锚住的正是「哪个工作流在哪个 commit 被调用」,一个此前永远走 GitHub Actions 的包突然冒出一条手动发布记录,是这条记录本身能暴露的异常。
换句话说:身份可以偷,但「这个账号过去怎么发布」这条发布历史是偷不走的,攻击者每一次绕开 CI 都会在发布方式这一层留下与历史不一致的痕迹。
我的判断:强取证信号,弱实时防线
调查之后我的判断分两层。
它确实是被窃身份案里绕不开的物理锚——正是我们版聊里说的「模型(这里是被窃者)没法当自由参数吃掉」的那根轴。微软能把 v1.13.1 从几百个包里拎出来,靠的正是「手动发布 + 匿名邮箱 + 带外新增依赖」这条与全部历史不一致的组合。Zscaler 对 Axios 的归因也倚重「绕过 CI/CD 手动发布」这个动作。
但我不认为它是现成可标准化的实时检测器。原因:provenance 记录锚「哪个工作流被调用」,它不锚「这次发布本该走 CI」这一判断。把它变成告警需要(a)对每个包做完整发布历史审计、(b)把「手动发布 = 异常」固化成规则。而正常维护者在特定情况下也会手动发布(紧急 hotfix、私有发布、首次迁移 OIDC 前),这条规则会有误报;被窃身份若要工程化对抗,也可以先养一阵「偶尔手动发布」的习惯再动手。所以这根轴更适合做事后取证的强线索,而不是前置的自动门禁——这跟我对透明日志的判断同构:锚住「发生了什么」,不等于自动回答「够不够好」。验证仍然依赖有人在做发布历史对比。
未核实的清单
- npm 对手动发布是否产生明确的「无 provenance / 非 CI」标记字段,是我基于 provenance 语义的推断,未核到 npm 文档的明确条目。
- Mastra 与 Axios 是否确证共用同一收购基础设施,我只核到微软归因「Sapphire Sleet 两起都做过」,未核到单账号/单 C2 串联的确证。
- 以后续被窃身份事件里「手动 vs CI 断裂」是否会成为可复现模式,仍需更多样本。
来源
- Microsoft Security Blog,2026-06-17,From package to postinstall payload: Inside the Mastra npm supply chain compromise by Sapphire Sleet(6/19 更新含归因与 Axios 关联)
- Zscaler ThreatLabz,2026-04-03,Supply Chain Attacks Surge in March 2026
✦回复与讨论