Axios NPM 供应链攻击分析
2026年3月31日,一个针对Axios npm包的供应链攻击事件被揭露,Axios是一个广受欢迎的JavaScript HTTP客户端,每周下载量超过1亿次。攻击者成功入侵了Axios主要维护者的npm账户(jasonsaayman),并发布了两个恶意版本:[email protected]和[email protected]。这些恶意版本被注入了一个名为[email protected]的“幽灵依赖”(phantom dependency),该依赖在此之前并不存在,且未被Axios代码实际导入。其唯一目的是执行一个postinstall脚本,以下载并运行一个针对macOS、Windows和Linux系统的跨平台远程访问木马(RAT)。
攻击溯源与机制
微软威胁情报团队将此基础设施和Axios npm攻击归因于Sapphire Sleet,一个北朝鲜国家支持的威胁行为者。此攻击遵循了近期高影响力供应链攻击的模式,即攻击者通过污染广泛采用的开源框架及其分发渠道来实现广泛的下游影响。
此次攻击的预谋阶段约在引爆前18小时进行。攻击者创建了一个账户(nrwise@proton[.]me),并发布了[email protected]的干净版本,以建立npm上的发布历史,从而降低自动化扫描器因包的新颖性而进行标记的可能性。恶意版本在协调世界时(UTC)周日深夜至周一凌晨发布,以最大限度地延长维护人员和npm安全团队响应的时间.
恶意包通过劫持的npm凭据手动发布,绕过了GitHub Actions的OIDC Trusted Publisher保护机制,导致在官方GitHub仓库中没有对应的提交、标签或发布记录。恶意1.14.1版本是使用被盗的npm访问令牌手动发布的,没有OIDC绑定,也没有gitHead信息,表明其并非通过Axios官方的GitHub Actions流程发布.
技术细节与载荷分析
受感染的Axios版本安装后,其postinstall脚本会部署一个经过高度混淆的Node.js Dropper脚本(setup.js)。该脚本使用两层编码方案,包括字符串反转、Base64解码和使用密钥OrDeR_7077的XOR加密,以逃避检测和分析。Dropper脚本会查询操作系统类型,然后向命令与控制(C2)服务器sfrclak[.]com:8000发送HTTP POST请求,根据受感染设备的操作系统(macOS、Windows或Linux)自动部署第二阶段的远程访问木马(RAT)负载.
所有三种平台特异性载荷(C++、PowerShell和Python)都实现了相同的RAT框架,具备侦察和建立持久性的功能,并增加了自毁功能以逃避检测.
恶意载荷执行流程示例:
// package.json 中的 postinstall 钩子示例
{
"name": "axios",
"version": "1.14.1",
"description": "Promise based HTTP client for the browser and node.js",
"main": "index.js",
"scripts": {
"postinstall": "node plain-crypto-js/setup.js"
},
"dependencies": {
"plain-crypto-js": "4.2.1"
}
}
// plain-crypto-js/setup.js (示意,实际代码会高度混淆)
const os = require('os');
const https = require('https');
const { exec } = require('child_process');
// 假设的C2服务器地址,实际可能加密或动态生成
const C2_SERVER = 'sfrclak[.]com:8000';
function downloadAndExecutePayload(osType) {
let payloadUrl = `https://${C2_SERVER}/payload?os=${osType}`;
// ... 发送HTTP POST请求到C2,获取平台特定RAT载荷 ...
// ... 执行载荷 ...
console.log(`Downloading and executing payload for ${osType}...`);
}
switch (os.platform()) {
case 'win32':
downloadAndExecutePayload('windows');
break;
case 'darwin':
downloadAndExecutePayload('macos');
break;
case 'linux':
downloadAndExecutePayload('linux');
break;
default:
console.log('Unsupported OS, exiting.');
}
恶意软件执行后会自毁,用干净的诱饵文件替换自身证据,增加了检测的难度.
受影响版本与用户响应
受此攻击影响的Axios版本为1.14.1和0.30.4。任何安装了这两个版本的项目都可能在安装时连接到恶意C2服务器并下载第二阶段恶意软件.
| 恶意版本 | 安全版本 (降级建议) | 影响范围 |
|---|---|---|
[email protected] |
[email protected] |
Windows, macOS, Linux系统 |
[email protected] |
[email protected] |
Windows, macOS, Linux系统 |
安装了axios版本1.14.1或0.30.4的用户应立即轮换其密钥和凭据,并降级到安全版本(1.14.0或0.30.3).
检测与缓解措施
供应链攻击的普遍性要求开发者和组织采取更严格的安全措施。以下是一些关键的检测和缓解策略:
- 依赖版本锁定与完整性验证: 严格锁定依赖版本(例如,使用确切版本而不是
^或~范围),并验证package-lock.json或yarn.lock文件的完整性。每次安装包时,包管理器会根据锁文件中存储的哈希值重新计算并比较下载文件的哈希值,不匹配则停止安装. - 禁用或审查安装脚本: npm的
preinstall、install和postinstall等生命周期钩子是恶意代码执行的常见载体. 在CI/CD环境中,应考虑使用npm ci --ignore-scripts来禁用安装脚本,或至少严格审查这些脚本的内容. - 持续依赖扫描: 定期使用软件组成分析(SCA)工具扫描项目依赖,识别已知漏洞和恶意包。像Secably这样的工具可以帮助自动化漏洞扫描和Web安全测试,检测供应链中的风险.
- 账户安全强化: 对npm账户启用双因素认证(2FA),并使用OIDC Trusted Publisher机制发布包,以加密方式将发布绑定到受信任的CI工作流程.
- 网络流量监控: 监控构建系统和生产环境的网络出口流量,识别对未知或可疑C2服务器的连接。这有助于发现恶意软件的“回传”行为. Zondex可用于发现暴露的服务和进行互联网范围的侦察,辅助识别异常网络活动。
- 私有注册表与依赖混淆防护: 在使用私有和公共npm注册表的混合环境中,配置包管理器优先从私有注册表拉取包,并使用作用域包(scoped packages,如
@myorg/mypackage)来避免依赖混淆攻击(Dependency Confusion). 依赖混淆攻击利用包管理器在多个注册表之间解析依赖的方式缺陷,通过在公共注册表上发布与私有包同名但版本更高的恶意包来注入恶意代码. - 防止Typosquatting: 警惕与流行包名称相似的包(例如,
crossenvvscross-env),这些是常见的Typosquatting攻击手法. 在安装新包时,应仔细核对包名称和来源。 - 供应链安全自动化平台: 采用端到端(end-to-end)的软件供应链安全管理平台,提供SBOM(Software Bill of Materials)管理、SCA、恶意包保护、CI/CD安全集成等功能,如Checkmarx One或Anchore.
- 环境隔离: 确保构建系统在隔离环境中运行,并仅具有执行其任务所需的最小权限。
其他相关NPM供应链攻击案例
ua-parser-js攻击 (CVE-2021-42740): 2021年10月,广受欢迎的npm包ua-parser-js被攻击者劫持其npm账户,发布了三个恶意版本(0.7.29,0.8.0,1.0.0)。这些版本被注入了恶意脚本,旨在安装加密货币矿工和窃取用户/凭据信息。受影响的系统可能被植入Monero挖矿程序或银行木马DANABOT. 该漏洞的CVSS 3.1基本评分为9.8 CRITICAL,原因是shell-quote包在处理Windows驱动器字母的正则表达式中存在缺陷,允许命令注入.// CVE-2021-42740 相关的 shell-quote 修复前代码示意 // 错误的正则表达式,例如: const regex = /^[A-z]:/; // 'Z' 和 'a' 之间包含 [, \, ], ^, _, ` 等字符 // 正确的应为: // const regex = /^[A-Za-z]:/;debug/chalk攻击: 2025年9月,攻击者通过针对维护者的鱼叉式网络钓鱼活动,入侵了npm维护者Josh Junon (qix) 的账户,导致包括debug、chalk、ansi-styles在内的18个流行包受损,这些包每周总下载量达26亿次。恶意代码旨在窃取加密货币.- Shai-Hulud Worm: 2025年9月,npm生态系统中出现首个自传播蠕虫Shai-Hulud,感染了500多个包。该攻击利用了TruffleHog秘密扫描工具来窃取凭据,并通过注入恶意的GitHub Actions工作流和自动发布恶意版本的其他包来传播.