打开网易新闻 查看精彩图片

axios 的周下载量超过 1 亿次。3 月 30 日,这个 JavaScript 世界里最基础的 HTTP 工具,有两个版本变成了远程控制的入口。

StepSecurity 的安全团队发现,axios@1.14.1 和 axios@0.30.4 被植入了恶意依赖。攻击者没有碰 axios 本身的代码——零行恶意代码在 axios 仓库里。他们用的是 npm 的依赖机制:在 package.json 里加了一个永远不会被 import 的包 plain-crypto-js@4.2.1,靠 postinstall 脚本在 install 阶段直接执行。

整个攻击窗口不到 40 分钟。两个版本间隔 39 分钟发布,恶意依赖提前 18 小时在 npm 上占位。这不是临时起意,是彩排过的剧本。

攻击链:2 秒内完成"安装-上线-自毁"

攻击链:2 秒内完成"安装-上线-自毁"

开发者跑 npm install 的时候,依赖解析还没结束,恶意脚本已经连上了攻击者的服务器。具体时序如下:

postinstall 脚本启动 → 识别操作系统(macOS/Windows/Linux)→ 下载对应平台的第二阶段载荷 → 执行远程访问木马(RAT)→ 删除自身文件 → 把 package.json 替换成干净版本。

事后你去 node_modules 里翻,plain-crypto-js 文件夹还在,但里面干干净净,像什么都没发生过。这种自毁设计让取证变得困难——攻击者甚至帮你打扫了现场

三个平台的载荷都是预编译好的。攻击者提前准备了 macOS、Windows、Linux 的二进制文件,说明他们对目标环境有明确预期。axios 的用户覆盖前端构建工具、后端服务、CLI 工具,几乎无处不在。

谁被波及:版本号对号入座

谁被波及:版本号对号入座

目前确认的两个毒版本:

• axios@1.14.1 —— 主版本线的最新恶意包

打开网易新闻 查看精彩图片

• axios@0.30.4 —— 0.x 遗留分支的异常更新

如果你在过去 24 小时内执行过 npm install axios 或自动更新了依赖,检查 lock 文件。版本号对上了,就按"已沦陷"处理。

StepSecurity 的检测来自他们的 AI Package Analyst 和 Harden-Runner 工具。后者是一个 GitHub Action,免费版支持公开仓库,目前有超过 1.2 万个公开项目在使用。这次能 caught in the act,靠的是监控 install 阶段的网络行为——恶意脚本在 2 秒内发出的 C2 请求被标记为异常

攻击者怎么拿到的发布权限

攻击者怎么拿到的发布权限

npm 包的发布依赖 maintainer 账号。axios 项目有多个维护者,攻击者通过劫持其中一个账号完成了发布。

具体是钓鱼、凭证泄露还是其他手法,目前尚未公开。但有一个细节值得注意:两个版本分别打在不同的分支上。1.14.1 走的主版本线,0.30.4 走的是 0.x 遗留线。这意味着攻击者熟悉 axios 的版本策略,知道哪些用户会锁定 0.x 版本。

「这不是 opportunistic,是 precision。」StepSecurity 的 Ashish Kurmi 在分析中用了这两个词。恶意依赖提前 18 小时占位,双版本 39 分钟内齐发,三平台载荷预置,自毁脚本清理痕迹——整个流程的紧凑程度,接近商业软件的发版节奏

axios 官方在发现问题后已下架这两个版本。但 npm 的缓存机制、私有镜像、lock 文件锁定,都可能让毒版本继续流传。

供应链攻击的"无代码化"趋势

供应链攻击的"无代码化"趋势

这次事件的一个关键特征:axios 源码仓库完全干净。如果你只审计 GitHub 上的代码,会发现不了任何问题。恶意代码只在 npm 发布的 tarball 里出现。

这种"构建时注入"或"发布端劫持"的模式,绕过了大多数开发者的安全假设。我们习惯了看 GitHub 的 commit 历史、跑 SAST 工具、依赖 GitHub 的 Dependabot 告警,但如果发布管道本身被渗透,源头再干净也没用

打开网易新闻 查看精彩图片

plain-crypto-js 这个名字也有讲究。它蹭的是 crypto-js 的知名度,版本号 4.2.1 比正版 crypto-js 的最新版还高,给人一种"更新、更好"的错觉。npm 的包名命名空间是扁平的,plain-crypto-js 和 crypto-js 毫无关系,但名字足够像。

攻击者还利用了 postinstall 脚本的执行时机。npm install 过程中,postinstall 在依赖解析完成后、整个 install 报告完成前运行。这意味着恶意代码执行时,npm 还没告诉你"安装成功"。等你看到提示,木马已经在后台了。

开发者现在该做什么

开发者现在该做什么

检查 lock 文件里的 axios 版本。如果是 1.14.1 或 0.30.4,按以下步骤处理:

1. 隔离受影响的机器,假设系统已沦陷

2. 检查 ~/.npm/_logs 目录,找 3 月 30 日左右的 install 日志

3. 审查该时间段内的网络连接记录,特别是指向未知域名的出站请求

4. 轮换所有可能暴露的密钥、token、凭证

长期防护上,可以考虑在 CI/CD 里接入 Harden-Runner 这类工具,监控 install 阶段的网络行为。或者锁定依赖版本,用 npm ci 替代 npm install,减少自动更新带来的暴露面。

axios 的维护者已经重置了相关账号凭证,但供应链攻击的修复从来不是单点问题。1 亿周下载量的基数下,即使很小的感染比例,绝对数字也很可观。

StepSecurity 在 4 月 1 日办了一场社区 town hall,YouTube 上有完整录像。他们正在准备完整的技术分析报告,包括载荷的逆向细节和 C2 基础设施的追踪。