紧急预警:2026年3月31日,全球最流行的 JavaScript HTTP 客户端库 Axios,其周下载量已超过1亿次,却遭遇了一场严重的供应链攻击。攻击者通过劫持维护者的 npm 账号,发布了包含跨平台远程控制木马(RAT)的恶意版本,潜在影响数百万开发者与企业系统。本文将完整复盘此次攻击的流程、技术细节,并提供详细的自查方法与防御策略。

一、事件速览:48 小时的“完美犯罪”
2026年3月30日至31日,攻击者精心策划了一场针对 Axios 的供应链投毒攻击,整个流程环环相扣。
| 时间线 (UTC) |
关键事件 |
| 3月30日 05:57 |
发布 plain-crypto-js@4.2.0(良性版本,用于建立信任历史) |
| 3月30日 23:59 |
发布 plain-crypto-js@4.2.1(恶意版本,内含恶意 postinstall 脚本) |
| 3月31日 00:00-00:39 |
劫持 Axios 维护者 npm 账号,手动发布两个恶意版本:1.14.1(1.x分支)、0.30.4(0.x分支) |
| 3月31日 03:00 |
npm 官方紧急下架恶意版本,并发布安全公告 |
| 3月31日 08:00 |
Axios 团队发布官方声明,确认账号被劫持,并提供修复方案 |
核心影响:恶意版本在线时间约3小时。在此期间,所有执行 npm install axios 且未锁定版本的用户均可能中招,攻击范围覆盖 Windows、macOS、Linux 全平台。
二、攻击链全解析:五步“投毒”流程
攻击者构建了一条 “账号劫持 → 依赖注入 → 混淆投递 → 远控植入 → 自毁灭迹” 的完整攻击链,极具隐蔽性。
1. 账号劫持:攻破“守门人”
攻击者通过未知手段(推测为钓鱼或凭证窃取)成功入侵了 Axios 核心维护者的 npm 账号。在修改邮箱后,攻击者绕过了基于 GitHub Actions 和 OIDC 的可信发布流程,获得了手动发布权限。这是整个攻击的起点与关键,没有账号控制权,后续一切操作都无法实施。
2. 依赖注入:埋下“暗桩”
恶意版本在其 package.json 中添加了一个 “幽灵依赖”:
"dependencies":{
"plain-crypto-js":"^4.2.1"
}
这个 plain-crypto-js 包从未被 Axios 源码 import/require,其唯一作用就是在 npm install 时,触发 postinstall 钩子来执行恶意脚本。值得注意的是,正常的 Axios 发布通过 GitHub Actions 自动化完成,而恶意版本是手动发布的,这恰恰绕过了自动化流程中的安全校验。
3. 混淆投递:伪装“良药”
攻击者采用了双重伪装策略来降低被发现的风险:
- 先发布良性版本:攻击者先发布了
plain-crypto-js@4.2.0,建立起看似正常的发布历史,避免因“全新包”而触发警报。
- 模仿知名库命名:包名模仿了知名的
crypto-js 库,容易让人放松警惕。
- 代码混淆:恶意脚本本身使用了混淆技术,增加了静态分析的难度。
当用户执行 npm install 时,这个恶意依赖会被自动安装,并立刻触发其 setup.js 脚本执行。
4. 远控植入:释放“木马”
setup.js 是整个攻击的核心载荷,其执行流程如下图所示:

5. 自毁灭迹:抹去“痕迹”
这是整个攻击链中最狡猾的一步——攻击完成后,恶意脚本会删除自身(setup.js)和恶意的 package.json,并用良性版本的文件进行替换,制造出“未被篡改”的假象,同时清理相关日志,防止被事后溯源。
这导致受害者在检查 node_modules 目录时完全看不到异常,大大增加了检测和取证的难度。
三、技术细节:RAT 如何“接管”你的设备
1. 平台差异化攻击
攻击者针对不同操作系统设计了特定的载荷投递路径和持久化手段:
| 系统 |
投递路径 |
伪装手段 |
恶意行为 |
| Windows |
%TEMP%\updater.exe |
伪装成系统更新程序 |
建立自启动,窃取浏览器凭证、SSH密钥 |
| macOS |
/Library/Caches/com.apple.act.mond |
伪装成 Apple 系统缓存文件 |
利用 launchd 实现持久化,监控键盘输入 |
| Linux |
/tmp/.systemd-update |
使用点号开头的隐藏文件,并设置 +wx 权限 |
植入 cron 定时任务,回传系统信息 |
2. C2 通信机制
恶意脚本通过 HTTP 协议与命令与控制(C2)服务器通信,传输内容包括:系统信息(OS 版本、CPU 架构、用户名)、已安装软件列表、网络配置以及窃取的敏感数据。
C2 服务器地址为 http://sfrclak.com:8000,该地址在事件曝光后已被关停,但攻击者可能已在短时间内收集了大量敏感信息。
四、如何自查:你是否已“中毒”?
快速检测三步法
-
检查 Axios 版本:
在命令行中运行:
npm list axios
如果显示版本为 1.14.1 或 0.30.4,则说明已经安装了恶意版本。
-
检查恶意依赖:
在项目根目录下,运行:
ls node_modules/plain-crypto-js
如果该目录存在,则你的项目可能已被感染。
-
扫描系统残留:
根据上文第三部分的路径表,检查你的系统中是否存在对应的可疑文件。
深度排查建议
- 检查近期的
npm install 日志,查找 plain-crypto-js 相关的安装记录。
- 监控系统的网络连接,查看是否有与可疑 IP(如已曝光的 C2 地址)的通信。
- 全面检查系统的自启动项、计划任务或
cron 作业,删除所有不明条目。
五、紧急修复:四步“解毒”指南
1. 降级并锁定版本
首先,将 Axios 降级到安全的版本:
- 1.x 分支用户(推荐):
npm install axios@1.14.0
- 0.x 分支用户:
npm install axios@0.30.3
其次,在 package.json 中添加覆盖配置,防止间接依赖错误地解析到恶意版本:
{
"dependencies": {
"axios": "1.14.0"
},
"overrides": { // 适用于 npm 8+ 版本
"axios": "1.14.0"
},
"resolutions": { // 适用于 Yarn
"axios": "1.14.0"
}
}
2. 清理恶意残留
彻底清除恶意软件及其相关文件:
3. 凭证轮换
立即更换所有可能已泄露的敏感凭证,包括:
- npm 与 GitHub 的个人访问令牌
- 各类云服务(AWS, GCP, Azure等)的密钥
- SSH 私钥
- 数据库连接密码
- 浏览器中保存的网站密码
4. 强化安全配置
- 启用 npm 双因素认证 (2FA):为你的 npm 账号添加额外保护。
- CI/CD 安全:在持续集成脚本中添加
--ignore-scripts 参数,默认禁用依赖包的自动执行脚本。
- 使用私有镜像:搭建或使用企业内部的 npm 镜像仓库,对所有同步的外部包进行安全审核。
- 定期依赖审计:使用
npm audit 或集成 Snyk、Dependabot 等工具,定期扫描项目依赖树中的安全风险。
六、供应链安全启示录
Axios 事件再次为整个技术社区敲响了警钟:开源软件供应链已成为黑客攻击的“重灾区”,即便是周下载量过亿、维护活跃的顶级库也无法幸免。这提醒我们,在享受开源便利的同时,必须建立起主动的防御意识。
开发者应做的 3 件事
- 版本锁定:在
package.json 中明确指定依赖版本(避免使用 ^ 或 ~),并提交 package-lock.json 或 yarn.lock 文件。
- 脚本管控:默认使用
npm install --ignore-scripts 安装依赖,仅对极少数可信的包执行安装脚本。
- 依赖审计:将
npm audit 纳入开发流程,并考虑使用 Snyk、Dependabot 等工具进行自动化的风险监控和修复。
企业级防御建议
| 防御层面 |
关键措施 |
| 依赖治理 |
建立内部镜像仓库,对所有引入的第三方包实施强制性安全审计。 |
| CI/CD 安全 |
启用工作流签名(如 GitHub 的 OIDC),严格限制生产环境的发布权限,采用不可变基础设施。 |
| 运行时防护 |
在服务器和工作站上部署端点检测与响应(EDR)工具,监控异常的网络连接、进程行为与文件操作。 |
| 应急响应 |
制定针对供应链攻击的专项应急预案,并定期进行演练。 |
七、总结:安全没有“免死金牌”
Axios 投毒事件是一次非常典型的软件供应链攻击。攻击者巧妙地利用了开源生态中固有的信任机制,以相对较低的成本获取了巨大的攻击面。这个事件深刻地提醒我们:绝不能将安全性完全寄托于第三方。
立即行动清单:
- ✅ 检查并修复项目中的 Axios 版本。
- ✅ 全面审计项目依赖树,清理所有可疑的包。
- ✅ 为你的 npm、GitHub 等关键账号启用双因素认证(2FA)。
- ✅ 在团队或公司层面,开始建立或完善依赖安全管理制度。
安全是一场持续不断的攻防战,而非一劳永逸的静态防御。在代码构成的世界里,最危险的威胁往往并非那些显而易见的漏洞,而是隐藏在看似正常的“信任”背后的暗箭。保持警惕,持续学习,是每位开发者必修的课程。如果你想深入探讨 Node.js 生态安全或其他 前端 开发话题,欢迎来 云栈社区 交流分享。