Axios NPM 包遭供应链攻击,恶意版本植入远程访问木马
文章摘要
2026 年 3 月 30 日,安全公司 StepSecurity 发现广泛使用的 JavaScript HTTP 客户端库 axios 在 NPM 上遭到供应链攻击。axios 是最流行的 JavaScript HTTP 客户端库,每周下载量超过 1 亿次,此次攻击影响范围极其广泛。该事件在 HN 上获得近 2000 点赞和 800 多条评论。
受影响版本: axios@1.14.1 和 axios@0.30.4 两个恶意版本。攻击者同时向 1.x 和 0.x 两个发布分支投毒,两个版本在 39 分钟内相继发布。
攻击机制: 恶意版本注入了一个新的依赖项 plain-crypto-js@4.2.1,该包从未在 axios 源代码中被导入。它的唯一用途是执行 postinstall 脚本,该脚本充当跨平台远程访问木马(RAT)投放器,针对 macOS、Windows 和 Linux 三个平台。执行后,恶意软件会自我删除并用干净版本替换自己的 package.json,以逃避取证检测。
攻击时间窗口: 恶意版本在 2026 年 3 月 31 日 UTC 00:21 至 03:15 期间处于活跃状态,窗口约 3 小时。
攻击者溯源: 微软威胁情报将此次攻击归因于朝鲜国家级黑客组织 Sapphire Sleet。Google 威胁情报组则将其归因于 UNC1069,一个与朝鲜有关的、以经济利益为动机的威胁行为者。
攻击特征分析: 这不是一次机会主义攻击,而是精心策划的行动。恶意依赖项提前 18 小时部署就位,三个操作系统的有效载荷预先构建完成,两个发布分支在 39 分钟内被相继投毒。攻击者通过劫持维护者账户来发布恶意版本。
缓解措施: pnpm 和 Bun 等包管理器要求手动批准 postinstall 脚本,这类攻击方式在这些环境中会被自动阻止。使用 npm 的项目应立即检查是否安装了受影响版本,并升级到安全版本。
HN 评论精华
“自带电池”生态 vs 最小依赖之争:
用户 bob1029 认为”自带电池”(batteries included)的生态系统是抵御包管理器漏洞的最强防线,主张通过第一方工具来最小化对第三方依赖的需求,尤其是 HTTP、TCP、JSON、加密等通用功能——这些正是攻击者最感兴趣的目标。用户 Groxx 则反驳说”自带电池”会导致僵化,认为”标准库是代码走向消亡的地方”。真正的解决方案应该是为库引入权限系统,让恶意行为更难以隐蔽。
各语言生态对比:
Go 语言因维护良好的标准库获得称赞,但其 HTTP 客户端和 JSON 实现的学习曲线受到一些批评。.NET 被频繁引用为真正”自带电池”的典范,提供了 LINQ、decimal 类型和验证功能而无需外部包。Python 尽管有标准库,但被认为”自带电池”程度不够,因为开发者习惯性地用 requests 替换 urllib。
攻击向量的技术分析:
用户 h4ch1 重点指出了攻击的巧妙之处:恶意代码并非嵌入 axios 源代码本身,而是通过注入一个假依赖 plain-crypto-js@4.2.1,该包仅包含一个 postinstall 脚本来部署 RAT。这种方式使得即使审查 axios 的代码差异也难以发现异常。pnpm 和 Bun 要求手动批准 postinstall 脚本的机制可以有效阻止此类攻击。
“Node 根本不需要 Axios”:
用户 afavour 讽刺地指出,Node.js 原生 fetch 支持已经存在多年,根本不需要 axios,但开发者因为习惯和 API 设计上的微小便利性差异仍然在使用它。这引发了关于”过度依赖”的广泛讨论——当一个简单功能有原生替代方案时,为何还要引入第三方库承担供应链风险?
AI 替代依赖的新思路:
用户 invaliduser 描述了一种新做法:使用 LLM 为解析器、数据清理和算法生成代码,而不是导入第三方库。这种方式用代码审查的确定性来换取依赖风险的不确定性。
供应链安全的系统性建议:
讨论中涌现出多种系统性解决方案:通过 Sigstore 进行供应链证明、企业镜像方案保护免受公共注册表被入侵的影响、vendoring(将依赖代码直接纳入项目)vs 包管理的权衡取舍。用户 lelanthran 主张通过编写针对性的 HTTP 实现来减少攻击面,而非导入包含大量未使用功能的综合性库。