axios 供应链攻击预警

[紧急预警] axios 被投毒!快查你的 package.json

安全

[紧急预警] axios 被投毒!快查你的 package.json

事件性质: npm 供应链投毒攻击 受影响版本: [email protected], [email protected] 攻击时间: 2026年3月31日 威胁等级: 🔴 严重 阅读时间: 约 10 分钟 | 字数: ~4500 字

axios 供应链攻击预警


01. 紧急自查与修复(必读)

受影响版本

分支恶意版本安全版本
1.x1.14.11.14.0
0.x0.30.40.30.3

一键自查命令

🔍 单项目检查(在项目根目录执行)

检查依赖版本

Terminal window
# 检查当前项目安装的 axios 版本
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"
# 检查恶意依赖目录是否存在
ls node_modules/plain-crypto-js 2>/dev/null && echo "⚠️ 检测到 plain-crypto-js,系统可能已感染"

🌐 全局批量检查(扫描电脑中所有项目)

在你的代码根目录(如 ~/Projects~/Documents)执行:

macOS / Linux

Terminal window
# 1. 批量查找所有 node_modules 中的恶意包
find . -name "plain-crypto-js" -type d 2>/dev/null | grep "node_modules" && echo "⚠️ 检测到恶意依赖"
# 2. 批量查找 package-lock.json 中的恶意版本
grep -rE '"axios":.*(1\.14\.1|0\.30\.4)"' . --include="package-lock.json"

Windows (PowerShell)

Terminal window
# 1. 批量查找恶意依赖目录
Get-ChildItem -Path . -Directory -Recurse -Filter "plain-crypto-js" -ErrorAction SilentlyContinue | Where-Object { $_.FullName -match "node_modules" }
# 2. 批量查找恶意版本
Get-ChildItem -Path . -File -Recurse -Filter "package-lock.json" | Select-String -Pattern 'axios.*1\.14\.1|axios.*0\.30\.4'

🖥️ 系统级 RAT 检查(最关键)

platform检查命令结果解读
macOS`[ -e “/Library/Caches/com.apple.act.mond” ] && echo ”🚨 已感染”
Linux`[ -e “/tmp/ld.py” ] && echo ”🚨 已感染”
WindowsTest-Path "$env:PROGRAMDATA\wt.exe"检查 %PROGRAMDATA%\wt.exe

一键检测脚本

Terminal window
# macOS / Linux 通用版
check_rat() {
if [ "$(uname)" = "Darwin" ]; then
[ -e "/Library/Caches/com.apple.act.mond" ] && echo "🚨 macOS RAT 文件存在,系统已失陷!" || echo "✅ macOS 安全"
else
[ -e "/tmp/ld.py" ] && echo "🚨 Linux RAT 文件存在,系统已失陷!" || echo "✅ Linux 安全"
fi
}
check_rat
Terminal window
# Windows PowerShell 版
if (Test-Path "$env:PROGRAMDATA\wt.exe") {
Write-Host "🚨 Windows RAT 文件存在,系统已失陷!" -ForegroundColor Red
} else {
Write-Host "✅ Windows 安全" -ForegroundColor Green
}

修复步骤

第一步:固定版本至安全范围

单项目修复

Terminal window
# 1.x 用户
npm install [email protected] --save-exact
# 0.x 用户
npm install [email protected] --save-exact

批量修复多个项目(在代码根目录执行):

Terminal window
# 批量固定所有项目到 1.14.0
find . -name "package.json" -not -path "*/node_modules/*" -execdir npm install [email protected] --save-exact --ignore-scripts \;

💡 参数说明

  • --save-exact:固定版本号(1.14.0 而非 ^1.14.0
  • --ignore-scripts:防止 postinstall 钩子再次触发

package.json 中添加强制锁定(覆盖间接依赖):

{
"dependencies": {
"axios": "1.14.0"
},
"overrides": {
"axios": "1.14.0"
},
"resolutions": {
"axios": "1.14.0"
}
}

第二步:删除 node_modules 重装

Terminal window
rm -rf node_modules package-lock.json
npm install --ignore-scripts

⚠️ --ignore-scripts 防止 postinstall 钩子再次触发

第三步:扫描系统残留文件

平台检查路径处理方式
macOS/Library/Caches/com.apple.act.mond如存在 → 系统已失陷,需重建
Windows%PROGRAMDATA%\wt.exe如存在 → 系统已失陷,需重建
Linux/tmp/ld.py如存在 → 系统已失陷,需重建

🚨 如发现 RAT 文件

  • 禁止就地清理 — RAT 可能已建立持久化或横向移动
  • 从可信镜像重建机器
  • 轮换所有凭证:npm tokens、GitHub tokens、AWS keys、云凭证、CI/CD secrets、.env 文件

02. 事件影响范围

影响范围数据图

1亿+ 周下载量的风险

axios 是 JavaScript 生态中最流行的 HTTP 客户端之一:

指标数据
周下载量8300 万+
依赖项目数174,025 个
覆盖范围前端框架、后端服务、企业应用、移动端

暴露窗口: 2026-03-31 00:21 UTC ~ 08:00 UTC(约 8 小时)

任何在此期间执行 npm install axiosnpm update 的项目都可能被感染。

CI/CD 流水线为何是重灾区

这次攻击对 CI/CD 环境的打击尤为致命:

  1. 自动触发 — 流水线每次构建都会执行 npm install,postinstall 钩子自动运行
  2. 高权限访问 — CI runner 往往拥有生产环境部署权限 and 敏感 secrets
  3. 难以追溯 — 临时构建环境销毁后,取证线索丢失
  4. 横向渗透 — 被感染的 CI 可能将恶意代码部署到所有下游环境

检查你的 CI/CD

Terminal window
# 审计 GitHub Actions 日志,查找恶意版本
grep -r "[email protected]\|[email protected]" .github/workflows/
# 所有在此期间运行过的 runner 视为失陷

03. 攻击手法复盘

攻击链流程图

劫持维护者账号:攻击源起

攻击者盯上了 axios 主要维护者 jasonsaayman 的 npm 账号:

  1. 账户篡改 — 将注册邮箱改为攻击者控制的 ProtonMail:[email protected]
  2. 获取 Token — 使用长期有效的 Classic npm access token
  3. 绕过 CI/CD — 直接通过 npm CLI 发布,跳过 GitHub Actions OIDC 可信发布机制

关键证据:GitHub Releases 页面没有 1.14.1/0.30.4 的发布记录,说明这不是通过正常 CI 流程发布的。

恶意依赖 plain-crypto-js:隐藏的木马下载器

攻击者精心策划了一个 Phantom Dependency 攻击:

干净版本 [email protected] 依赖:
├── follow-redirects
├── form-data
└── proxy-from-env
恶意版本 [email protected] 依赖:
├── follow-redirects
├── form-data
├── proxy-from-env
└── plain-crypto-js@^4.2.1 ← 唯一新增项

关键点:对 axios 全部 86 个源文件进行搜索,plain-crypto-js 的引用次数为 。这个依赖存在的唯一目的就是触发 postinstall 钩子。

投放器 setup.js 的混淆技术

  • 双层混淆:XOR + Base64
  • 敏感字符串运行时解码
  • 解码密钥:"OrDeR_7077"

解码后的核心字符串包括 C2 地址 http://sfrclak.com:8000/ 和各平台的攻击载荷。

自清理机制:为何你发现不了?

这是这次攻击最狡猾的设计 — 执行后自我销毁

setup.js 执行后:
1. fs.unlink(__filename) → 删除自身
2. fs.unlink("package.json") → 删除含 postinstall 的 manifest
3. fs.rename("package.md", "package.json") → 替换为干净的 stub

攻击者预置了一个干净的 package.md(版本 4.2.0,无 postinstall 钩子),在恶意代码执行后将其重命名为 package.json

结果:事后检查时,package.json 看起来完全正常,没有任何可疑的 scripts 字段。

检测提示:即使 package.json 被恢复,只要 node_modules/plain-crypto-js/ 目录存在,就说明系统已被感染。


04. 防御建议

npm 安全防御策略框架

别再信任 latest

这次攻击再次敲响警钟:永远不要在生产环境使用 latest 标签

// ❌ 危险做法
{
"dependencies": {
"axios": "latest"
}
}
// ✅ 安全做法
{
"dependencies": {
"axios": "1.14.0"
}
}

如何配置 npm 安全策略

1. 锁定依赖版本

Terminal window
# 使用精确版本号
npm install [email protected] --save-exact
# 或在 .npmrc 中配置
save-exact=true

2. 禁用生命周期脚本

.npmrc
ignore-scripts=true
# 或在安装时指定
npm install --ignore-scripts

3. 启用安全审计

Terminal window
# 在 CI 中添加
npm audit --audit-level=high
# 使用 npm audit fix 自动修复
npm audit fix

4. 使用锁定文件

Terminal window
# 始终提交 package-lock.json
# CI 中使用 npm ci 而非 npm install
npm ci --ignore-scripts

5. 监控依赖变化

Terminal window
# 检查依赖树变化
npm ls --depth=0
# 使用工具监控
npx npm-check-updates

6. 网络层阻断

Terminal window
# 阻断已知 C2 域名
echo "0.0.0.0 sfrclak.com" | sudo tee -a /etc/hosts

总结

关键点行动项
🔴 立即检查运行自查命令,确认 axios 版本
🟠 如已感染降级版本 + 删除 node_modules + 轮换凭证
🟢 长期防御锁定版本 + 禁用 scripts + 启用审计

记住:供应链攻击不需要你的代码有漏洞,只需要你信任的依赖被攻破。今天是 axios,明天可能是另一个包。

发布于: 2026年4月1日 · 修改于: 2026年4月2日