npm 热门库 axios 遭遇供应链攻击
原创 二道 2026-03-31 13:50 广东

npm 热门库 axios 遭遇供应链攻击:维护者账号被劫持,恶意版本植入跨平台远程控制木马
2026年3月31日,网络安全机构StepSecurity发布紧急安全通告:JavaScript生态最主流的HTTP客户端库axios,其核心维护者的npm账号遭攻击者劫持,攻击者绕过项目正常的GitHub Actions CI/CD发布流程,手动向npm官方仓库推送了两个携带恶意代码的版本——axios@1.14.1与axios@0.30.4。
此次攻击是一次高度专业化的供应链投毒事件:恶意版本并未直接修改axios源码,而是通过注入虚假依赖包触发自动执行的恶意脚本,针对Windows、macOS、Linux三大主流操作系统植入跨平台远程访问木马(RAT),并可对接攻击者控制的命令与控制(C2)服务器实现持久化远程控制。恶意软件还内置了完善的自清理机制,执行后会自动销毁恶意文件、伪造合法配置文件,以此规避常规安全审计。
作为JavaScript生态下载量最高的HTTP客户端,axios每周npm下载量超3亿次,广泛应用于前端项目、Node.js服务、CI/CD工具链等几乎所有JavaScript相关场景,此次攻击潜在影响范围极大,所有使用npm管理依赖的开发者与企业均需立即开展自查与处置。
一、完整攻击时间线
此次攻击经过了周密的预部署,攻击者提前18小时完成恶意依赖的铺垫,全程操作仅用不到24小时,最大限度规避安全工具的检测:
1. 2026-03-30 05:57 UTC:攻击者使用匿名邮箱nrwise@proton.me注册npm账号,发布伪装包plain-crypto-js@4.2.0,该包完全复刻合法crypto-js的源码,无任何恶意代码,仅用于建立包的发布历史,规避“零历史新包”的安全告警。
2. 2026-03-30 23:59 UTC:攻击者发布plain-crypto-js@4.2.1,在包中加入恶意postinstall自动执行钩子与混淆后的木马投放脚本,完成攻击载荷的预部署。
3. 2026-03-31 00:21 UTC:攻击者使用被劫持的axios核心维护者jasonsaayman的npm账号(邮箱已被篡改至攻击者控制的ifstap@proton.me),手动发布axios@1.14.1,向包中注入恶意依赖plain-crypto-js@^4.2.1,覆盖1.x主流版本用户。
4. 2026-03-31 01:00 UTC:时隔39分钟,攻击者再次发布axios@0.30.4,以相同方式注入恶意依赖,覆盖0.x legacy分支用户,最大化攻击影响范围。
二、攻击技术细节拆解
1. 核心入口:维护者账号劫持
攻击者攻陷了axios项目核心维护者jasonsaayman的npm账号,篡改了账号绑定的邮箱,获取了账号的长期有效经典访问令牌。
合法的axios 1.x版本均通过GitHub Actions的npm OIDC可信发布者机制发布,发布行为与GitHub工作流密码学绑定,且带有对应的git提交记录与标签;而两个恶意版本均为攻击者手动通过npm CLI发布,无OIDC可信发布标识、无对应的GitHub提交与标签,这是区分合法与恶意版本的核心 forensic 特征。
2. 攻击触发:无引用的虚假依赖注入
两个恶意axios版本均未修改自身源码,仅在package.json的依赖中新增了plain-crypto-js@^4.2.1——该包从未出现在任何合法axios版本中,且在axios全量86个源码文件中,没有任何一处import或require引用该包。
其唯一作用,是在开发者执行npm install/npm update时,被npm自动解析安装,并触发其内置的postinstall钩子,自动执行node setup.js恶意脚本,全程无需用户任何额外操作。
3. 恶意载荷:跨平台RAT投放与执行
setup.js是经过两层混淆处理的木马投放器,所有敏感字符串(C2地址、系统命令、文件路径等)均经过Base64编码与XOR加密处理,仅在运行时解码,以此规避静态安全扫描。
投放器会自动识别目标操作系统,针对性投放对应架构的第二阶段RAT载荷,所有载荷均从同一个C2服务器获取:
• macOS平台:写入并执行AppleScript脚本,从C2服务器下载macOS专属RAT二进制文件,保存至伪装成系统缓存的路径/Library/Caches/com.apple.act.mond,赋予执行权限后后台启动,执行完成后删除脚本文件,仅保留恶意二进制文件。
• Windows平台:先复制PowerShell二进制文件至%PROGRAMDATA%\wt.exe(伪装成Windows终端程序),再写入并执行VBScript脚本,从C2服务器获取PowerShell格式的RAT脚本,绕过执行策略静默运行,执行完成后自删除所有临时脚本,仅保留伪装的PowerShell副本。
• Linux平台:直接执行shell命令,从C2服务器下载Python格式的RAT脚本至/tmp/ld.py,通过nohup后台启动执行。
为规避网络流量检测,三个平台的请求均使用packages.npm.org/前缀作为POST请求体,伪装成正常的npm registry通信,极易绕过SIEM规则与常规网络审计。
4. 自清理机制:深度规避事后检测
在完成RAT投放后,恶意脚本会立即执行三步自清理操作,彻底销毁攻击痕迹:
1. 删除自身setup.js恶意脚本文件
2. 删除带有postinstall恶意钩子的package.json文件
3. 将预植入的干净package.md文件重命名为package.json,替换为无恶意内容的合法配置文件
清理完成后,即使开发者事后检查node_modules中的plain-crypto-js目录,也只会看到完全合法的配置文件,无任何恶意代码痕迹,常规的npm audit与手动目录检查均无法发现攻击痕迹。仅需注意:只要node_modules中存在plain-crypto-js目录,即可判定恶意脚本已执行,系统已失陷。
三、失陷指标(IOC)
恶意npm包
• axios@1.14.1
• axios@0.30.4
• plain-crypto-js@4.2.1
网络指标
• C2域名:sfrclak.com
• C2 IP地址:142.11.206.73
• C2完整地址:http://sfrclak.com:8000/6202033
文件系统指标
• macOS:/Library/Caches/com.apple.act.mond
• Windows:%PROGRAMDATA%\wt.exe
• Linux:/tmp/ld.py
恶意控制账号
• 被劫持npm账号:jasonsaayman(篡改后邮箱ifstap@proton.me)
• 恶意包发布账号:nrwise(邮箱nrwise@proton.me)
四、自查指南:快速判断是否中招
1. 检查项目是否使用恶意axios版本
在项目根目录执行以下命令,若有输出则说明项目依赖了恶意版本:
# 检查项目依赖中的axios版本
npm list axios 2>/dev/null | grep -E "1\.14\.1|0\.30\.4"
# 检查lock文件中的axios版本
grep -A1 '"axios"' package-lock.json | grep -E "1\.14\.1|0\.30\.4"
2. 检查是否存在恶意依赖包
在项目根目录执行以下命令,若输出POTENTIALLY AFFECTED则说明已安装恶意依赖,恶意脚本大概率已执行:
ls node_modules/plain-crypto-js 2>/dev/null && echo "POTENTIALLY AFFECTED"
3. 检查系统是否存在RAT持久化文件
# 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
4. 额外检查项
需同步排查CI/CD流水线日志,若有任何流水线执行过恶意版本的npm install操作,需判定该流水线环境已失陷。
五、紧急修复与长效防护方案
紧急处置步骤
1. 立即降级并锁定axios至安全版本
1.x分支用户执行:
npm install axios@1.14.0
0.x分支用户执行:
npm install axios@0.30.3
同时在package.json中添加overrides与resolutions配置,彻底阻断传递性依赖解析到恶意版本:
{
"dependencies": { "axios": "1.14.0" },
"overrides": { "axios": "1.14.0" },
"resolutions": { "axios": "1.14.0" }
}
2. 彻底移除恶意依赖包
rm -rf node_modules/plain-crypto-js
npm install --ignore-scripts
3. 失陷系统处置
若检测到RAT持久化文件,或确认恶意脚本已执行,必须将系统判定为完全失陷,不可尝试本地清理,需从已知干净的镜像重建系统环境。
4. 全量凭据轮换
所有安装过恶意版本的机器,需立即轮换所有敏感凭据,包括但不限于:npm访问令牌、云服务AK/SK、SSH私钥、CI/CD流水线密钥、.env文件中的所有敏感配置。
5. 网络层面拦截
在防火墙、DNS层面封禁C2地址,阻断恶意回连:
# Linux 防火墙封禁
iptables -A OUTPUT -d 142.11.206.73 -j DROP
# macOS/Linux hosts文件封禁
echo "0.0.0.0 sfrclak.com" >> /etc/hosts
长效防护建议
1. 在CI/CD流水线的npm安装命令中,默认添加--ignore-scripts参数,禁用所有自动执行的生命周期钩子,阻断此类攻击的核心触发入口。
2. 对核心依赖启用版本锁定,禁止自动更新小版本/补丁版本,仅手动审核后升级。
3. 定期审计项目依赖,排查“仅出现在依赖清单、无任何源码引用”的幽灵依赖,此类依赖是供应链投毒的高风险信号。
4. 优先使用通过OIDC可信发布机制发布的npm包,手动发布的包需额外加强安全审核。
六、安全警示
此次攻击是npm生态近年来影响范围最广、技术成熟度最高的供应链攻击之一,攻击者精准瞄准了JavaScript生态的核心基础设施,通过劫持维护者账号、注入幽灵依赖、利用生命周期钩子触发攻击、内置自清理机制规避检测,形成了完整的攻击闭环,对常规的安全防护手段有极强的绕过能力。
对于开源软件供应链安全,仅依靠上游项目的安全保障已不足以抵御此类定向攻击,开发者与企业需建立完整的依赖安全管控体系,从依赖准入、版本锁定、执行权限管控、流量审计等多个维度构建防护能力,最大限度降低供应链攻击带来的风险。