近日,axios 的首席维护者 Jason Saayman 在 GitHub 发布了一篇官方事后分析(Post-Mortem),详细说明了项目遭遇的 npm 供应链攻击事件。每周下载量高达 1.4 亿次的 axios 是 npm 生态的核心依赖之一,此事引发了社区广泛关注。
虽然已有大量技术分析,但这份由维护者本人撰写的报告,提供了官方视角下的完整事件脉络。本文梳理了该 Issue 的正文、评论以及 Jason 本人的回复,揭示了一些超越单纯技术层面的深刻洞见。
官方措辞与个人回应的“温差”
一个值得玩味的细节是,帖子正文与 Jason 在评论区的回复,呈现出两种截然不同的语气。
正文措辞极为审慎,使用了诸如“我们正在积极调查”、“目前尚无确认的细节可以分享”等经过斟酌的公关语言,为后续行动留有余地。
然而,当评论者追问社会工程学攻击的具体细节时,Jason 的回复则变得直接且具体。他详细描述了攻击者如何一步步获取他的信任。这种“温差”表明,正文很可能经过了法律或公关流程的审核,而 Jason 本人则选择在评论中披露更多事实。
攻击者是如何得手的:一场精心策划的骗局
Jason 在评论中拆解了整个攻击流程,其专业程度远超普通钓鱼邮件。
第一步:身份伪装
攻击者没有虚构身份,而是选择冒充一家真实公司的创始人,克隆了其个人形象与公司品牌,这大大增加了可信度。
第二步:环境构建
攻击者邀请 Jason 加入一个“真实的 Slack 工作区”。这个 Slack 并非伪造的网页,而是一个精心布置的真实环境:里面有同步该公司真实 LinkedIn 帖子的频道,有伪造的团队成员档案,甚至还加入了其他开源维护者的资料。加入其他 OSS 维护者资料这一手尤为高明,它让目标觉得这家公司与开源社区有天然联系,从而降低了戒备。
第三步:会议邀约
攻击者安排了一场 Microsoft Teams 会议,并且营造出有多人与会的假象。这非常关键,因为大多数人会认为“钓鱼”是一对一的私下行为,而一场正式的多人商务会议则显得合理且专业。
第四步:关键一击
在会议过程中,攻击者提示 Jason 其系统有某些组件“过期了”。Jason 在当时的情境下,认为这可能是 Teams 客户端所需的东西,便安装了所谓的“更新”。正是这个更新,实则是远程访问木马(RAT)。Jason 事后评价,整个攻击“协调极其周密,看起来完全合法,并以专业的方式进行”。
2FA 为何失效?OIDC 发布机制的缺失
事件发生后,一个自然的问题是:npm 不是对重要包强制要求双因素认证(2FA)了吗?Jason 的答复是:“我的账户确实启用了 2FA。” 然而,一旦 RAT 植入成功,攻击者便获得了对机器的完全控制权。他们可以查看屏幕、截取验证码,甚至在用户无感知的情况下完成整个认证流程,2FA 形同虚设。
评论区有进一步的讨论指出,npm 目前缺乏一项关键的安全功能:允许包维护者强制要求只能通过 OIDC(OpenID Connect)凭证发布,拒绝所有手动令牌发布。实际上,axios 的 v1.x 分支自 2023 年起就已使用 GitHub Actions 的 OIDC 受信发布者进行发布,其最后几个正版版本都附带了可验证的来源证明(provenance attestation)。
但攻击者绕过了 CI/CD 流水线,直接利用盗取的令牌手动发布了恶意版本 axios@1.14.1。这个版本没有关联的 gitHead 引用,也没有对应的 GitHub 提交记录。遗憾的是,npm 并未提供设置来阻止这种绕过自动化流程的手动发布。
更大的背景:这不是孤立事件
在帖子的评论中,加密货币安全研究员 tayvano 提供了一个更广阔的视角。她指出,此次攻击手法与谷歌威胁情报团队文档中记录的 UNC1069(又名 BlueNoroff)组织高度吻合,这是一个由国家支持的攻击团伙。
该组织长期以加密货币行业为目标,其套路如出一辙:
- 伪装成行业相关人士(投资人、合作方)建立联系。
- 花费数周时间培养信任,不急不躁。
- 安排一场“多人视频会议”。
- 在会议中触发“系统更新”提示,诱导安装 RAT。
tayvano 表示,攻击目标从“有钱的个人”(加密货币创始人、风投)转向“高影响力的开源维护者”,这一趋势令人担忧。攻击一个广泛使用的开源库,其潜在收益可能远超攻击单个富有的个体。
另一位评论者 voxpelli 也分享了几周前的类似遭遇:他被邀请上一档播客,进入 Slack 群组,在长时间交流后,对方以“录制网站故障”为由,提示他安装一个未经公证签名的原生应用。他因警惕而幸免,并推测对方的目标可能是他维护的 Mocha 测试框架。
后续措施与反思
Jason 在帖子末尾列出了“正在做出的改变”清单,包括重置所有设备凭证、引入不可变发布设置、全面迁移到 OIDC 发布流程、提升整体安全基线和更新所有 GitHub Actions 以遵循最佳实践等。他强调:“这份清单并非终点。”
值得注意的是,清单中并未包含“使用硬件安全密钥”。有评论者指出,在机器已被 RAT 完全控制、会话处于活跃状态时,即便是 FIDO2 硬件密钥也可能无法提供有效保护。
帖子最后,Jason 特别感谢了另一位维护者 DigitalBrainJS。正是他在发现 Jason 的账号被用于异常删除 Issue 后,迅速采取行动,提交了版本废弃(deprecation)的 PR 并联系 npm 官方,才使得此次事件在短短三小时内得到控制,未造成更广泛的破坏。
结语:对开源维护者的警示
这起事件如果仅从技术层面分析载荷、混淆手法和入侵指标,很容易忽略其背后的复杂性。Jason 的复盘提供了另一个至关重要的视角:一个真实的人,在面对一场针对其个人量身定制的、高度专业化的社会工程学攻击时,做出了在当时情境下看似合理的决定,最终导致整个软件供应链被短暂污染。
这绝非一次简单的“误点链接”。它揭示出,高影响力开源项目的维护者已成为高级别社会工程学攻击的明确目标。正如 Jason 在正文中所写:
“拥有高影响力开源包的维护者是复杂社会工程学的活跃目标。无论是在注册表层面还是个人层面,都需要保持高度警惕。”
在 云栈社区 等开发者聚集地,此类关于安全实践与供应链风险的讨论正变得愈发重要。这句话在两年前听来或许像是陈词滥调,但今天,有了 axios 事件作为鲜活的注脚,它值得每一位开源参与者,尤其是核心项目的维护者,深刻铭记。