CVE-2026-40175:Axios如何让1.2亿周下载量的HTTP客户端变成云环境杀手
2026年4月10日npm生态迎来本年度首个CVSS满分10.0漏洞CVE-2026-40175。这个存在于全球最流行HTTP客户端Axios中的漏洞通过一条隐蔽的原型污染Gadget链无需攻击者直接输入恶意数据即可实现HTTP请求拆分、SSRF、云元数据窃取最终可能导致整个云环境被完全接管。本文将从技术原理、攻击链、影响范围、修复方案到未来趋势为你带来全网最全面的深度解析并提供可直接落地的检测脚本、修复清单和Ansible批量修复工具。一、漏洞技术深度解析一条完美的原型污染Gadget链要理解CVE-2026-40175的真正危险我们必须先拆解这条被安全研究人员称为教科书级的攻击链。它巧妙地结合了JavaScript语言的原生特性、Axios的设计缺陷和云原生环境的普遍弱点形成了一个几乎无解的攻击闭环。1.1 原型污染JavaScript生态的原罪原型污染是JavaScript特有的一种漏洞类型源于其基于原型链的继承机制。当攻击者能够向Object.prototype添加或修改属性时所有JavaScript对象都会自动继承这些属性。过去5年npm生态中已经发现了数百个原型污染漏洞涉及qs、minimist、ini、lodash等几乎所有最流行的工具库。这些漏洞通常被认为是低危或中危因为单独的原型污染很难直接导致严重后果。但CVE-2026-40175的出现彻底改变了这一现状——它为所有原型污染漏洞提供了一个通用的、高危害的利用Gadget。1.2 Axios配置合并机制的致命缺陷Axios的核心设计之一是配置合并它会将用户传入的配置与默认配置进行深度合并生成最终的请求配置。问题出在lib/core/mergeConfig.js文件中的合并逻辑// Axios 1.14.0及更早版本的合并逻辑简化版functionmergeConfig(defaultConfig,userConfig){constconfig{};// 合并默认配置for(constkeyindefaultConfig){config[key]defaultConfig[key];}// 合并用户配置for(constkeyinuserConfig){// 这里没有检查key是否来自Object.prototypeconfig[key]userConfig[key];}returnconfig;}注意到问题了吗for...in循环会遍历对象自身的属性以及原型链上的所有可枚举属性。这意味着如果Object.prototype被污染了一个名为headers的属性Axios会自动将其合并到最终的请求配置中。[!CAUTION]更致命的是这个合并过程是自动发生的发生在每一个Axios请求发送之前完全不需要开发者做任何操作。1.3 CRLF注入从原型污染到请求拆分仅仅合并配置还不足以造成严重危害真正的漏洞点在于lib/adapters/http.js文件中的HTTP头处理逻辑// Axios 1.14.0及更早版本的头处理逻辑简化版functionsetHeaders(request,headers){for(constnameinheaders){constvalueheaders[name];// 这里没有过滤CRLF字符request.setHeader(name,value);}}Axios在设置HTTP头时完全没有过滤回车换行CRLF字符。这意味着如果攻击者通过原型污染注入了一个包含\r\n的头值就能实现HTTP请求拆分Request Splitting。例如攻击者可以污染Object.prototype如下Object.prototype.headers{X-Malicious-Header:value\r\nX-Aws-Imdsv2-Token: TOKEN\r\n};当Axios发送任何请求时都会自动添加这个恶意头导致原始请求被拆分成两个独立的HTTP请求。1.4 完整攻击链如何一步一步接管你的云环境现在让我们把所有环节串联起来看看攻击者是如何利用CVE-2026-40175接管一个运行在AWS上的Node.js应用的入口点攻击者利用应用中某个第三方依赖如qs6.9.0的原型污染漏洞向Object.prototype注入恶意的headers属性自动合并Axios在处理下一个请求时自动将恶意headers合并到请求配置中请求拆分恶意头中的CRLF字符将原始请求拆分成两个请求IMDSv2绕过第二个请求被发送到AWS元数据服务169.254.169.254获取临时访问凭证凭证窃取攻击者通过DNS重绑定、响应拆分等方式获取到元数据服务返回的凭证云环境接管使用窃取的凭证访问AWS S3、EC2、Lambda等服务实现数据泄露、挖矿甚至远程代码执行这条攻击链的可怕之处在于每一步都是自动发生的完全不需要用户交互也不会在应用日志中留下任何明显的痕迹。二、影响范围深度剖析比你想象的要广泛得多CVE-2026-40175的影响范围远远超出了大多数人的预期。它不仅影响直接使用Axios的项目还影响所有间接依赖Axios的项目甚至包括那些你可能从未听说过的底层库。2.1 版本影响矩阵Axios版本系列受影响版本修复版本风险等级1.x系列1.0.0 1.15.01.15.0严重0.x系列0.31.00.31.0严重[!WARNING]重要提示0.x系列的修复版本最初被错误地标记为0.3.1官方后来更正为0.31.0。请务必升级到正确的版本避免因版本号错误导致修复失败。2.2 隐蔽的间接依赖陷阱这是CVE-2026-40175最危险的一点即使你的package.json中没有Axios你仍然可能受到影响。根据npm官方的依赖分析目前有超过50万个npm包依赖Axios其中包括几乎所有主流的第三方API SDK如Stripe、Twilio、SendGrid等许多流行的Node.js框架和中间件AWS SDK v2注意AWS SDK v3使用自己的HTTP客户端不受影响大量的内部工具和企业级应用这意味着你可能在毫不知情的情况下通过一个看似无害的依赖引入了这个致命漏洞。2.3 不同应用场景的风险等级评估应用类型风险等级主要危害云原生Serverless应用Lambda、函数计算极高直接窃取云凭证导致整个云账号被接管Node.js后端服务和微服务极高SSRF、数据泄露、远程代码执行Next.js/Nuxt.js SSR应用高服务器端数据泄露、云凭证窃取Electron桌面应用中本地文件读取、系统信息泄露纯前端浏览器应用低主要用于CSRF攻击和用户数据窃取2.4 关于Node.js底层已修复的争议部分安全研究人员指出在标准Node.js环境中Node.js运行时已经在底层阻止了包含CRLF字符的HTTP头的发送。这意味着在大多数情况下CVE-2026-40175实际上无法被利用。然而我们必须强调这个结论只适用于标准Node.js环境和默认的HTTP适配器。在以下情况下漏洞仍然可以被成功利用使用了自定义的HTTP客户端适配器运行在非标准的JavaScript环境中如Deno、Bun、Electron应用使用了HTTP代理存在其他可以绕过Node.js安全限制的漏洞[!NOTE]安全防御的原则是纵深防御。即使这个漏洞在当前环境下无法被利用我们也应该尽快修复它以消除未来可能出现的任何风险。三、真实攻击场景复现最小可复现案例为了让你更直观地理解这个漏洞我们提供了一个最小可复现案例。你可以在本地运行这段代码亲眼看到攻击效果。// 注意仅用于安全研究禁止用于非法用途constaxiosrequire(axios);constqsrequire(qs);// 步骤1利用qs的原型污染漏洞污染Object.prototype// 这模拟了攻击者通过某个第三方依赖实现原型污染的过程constmaliciousInput{__proto__:{headers:{X-Injected-Header:injected-value\\r\\nX-Another-Header:another-value}}};qs.parse(maliciousInput,{allowPrototypes:true});// 步骤2发送一个完全正常的Axios请求// 注意这里没有传递任何恶意参数axios.get(https://httpbin.org/headers).then(response{console.log(请求头,response.data.headers);// 你会看到输出中包含我们注入的两个额外头}).catch(error{console.error(请求失败,error);});运行这段代码你会发现即使我们在调用axios.get时没有传递任何头信息返回的请求头中仍然包含了我们通过原型污染注入的两个额外头。这就是CVE-2026-40175的可怕之处它完全不需要你做任何错误的操作只要你的依赖链中有一个原型污染漏洞攻击者就能控制你的所有HTTP请求。四、官方修复方案技术解读与临时缓解措施4.1 官方修复方案分析Axios团队在2026年4月10日紧急发布了1.15.0和0.31.0两个修复版本。这次修复主要做了两个关键改动在配置合并时过滤原型链属性修改了mergeConfig函数只合并对象自身的属性不再继承原型链上的属性在设置头时过滤CRLF字符在http.js适配器中添加了CRLF字符过滤逻辑防止请求拆分修复后的mergeConfig函数关键代码如下// Axios 1.15.0修复后的合并逻辑for(constkeyinuserConfig){if(Object.prototype.hasOwnProperty.call(userConfig,key)){config[key]userConfig[key];}}这个修复方案从根本上切断了原型污染到Axios配置的传递路径是一个彻底且有效的修复。4.2 临时缓解措施按有效性排序如果你暂时无法升级Axios可以采取以下临时缓解措施按有效性从高到低排序使用--disable-protodelete启动Node.js进程node--disable-protodelete app.js这是最有效的临时缓解措施它会完全禁用Object.prototype的修改从根源上阻止原型污染攻击。在应用启动时冻结Object.prototypeObject.freeze(Object.prototype);这可以防止攻击者修改Object.prototype但无法阻止已经被污染的原型链。使用npm overrides强制升级依赖中的Axios版本在package.json中添加以下内容overrides:{axios:^1.15.0}这会强制所有依赖使用最新版本的Axios即使它们在package.json中指定了旧版本。五、前瞻性安全思考CVE-2026-40175给我们的启示CVE-2026-40175不仅仅是一个普通的漏洞它更是一面镜子照出了npm生态和云原生时代安全防御体系的系统性缺陷。5.1 npm生态的系统性安全危机npm生态的依赖地狱问题已经存在多年但CVE-2026-40175将这个问题的严重性提升到了一个新的高度。一个被1.2亿个项目依赖的库一个存在了6年的设计缺陷直到2026年才被发现并修复。这告诉我们我们的软件供应链比我们想象的要脆弱得多。我们每天都在使用的大量开源库可能隐藏着我们从未意识到的致命漏洞。5.2 原型污染漏洞的演进与未来趋势过去原型污染漏洞被认为是低危漏洞因为很难直接利用。但CVE-2026-40175的出现标志着原型污染漏洞进入了一个新的时代。未来我们将会看到更多类似的Gadget链被发现。攻击者会越来越多地利用原型污染作为入口点结合其他库的设计缺陷实现高危害的攻击。5.3 云原生时代SSRF防御的新范式在云原生时代SSRF漏洞的危害被无限放大了。一个普通的SSRF漏洞现在可以直接导致整个云环境被接管。传统的SSRF防御措施如禁止访问内网IP已经不再足够。我们需要建立新的防御范式严格限制云元数据服务的访问权限使用IMDSv2并强制开启会话令牌对出站HTTP请求进行严格的过滤和监控最小化云服务账号的权限5.4 从被动补丁到主动防御CVE-2026-40175再次证明了被动补丁模式的局限性。当一个漏洞被公开时攻击者已经可以利用它来攻击数百万个未打补丁的系统。未来的安全防御必须从被动补丁转向主动防御采用默认安全的设计原则在语言层面和运行时层面添加安全防护建立持续的供应链安全监控机制推广SBOM软件物料清单的使用六、总结与行动指南CVE-2026-40175是2026年迄今为止最严重的npm漏洞它影响了全球超过1000万个项目。虽然这个漏洞在标准Node.js环境中很难被利用但我们仍然强烈建议所有使用Axios的用户尽快升级到最新版本。立即采取以下行动升级Axios到1.15.0或0.31.0及更高版本使用npm ls axios命令检查所有间接依赖是否包含受影响的版本在package.json中添加overrides强制所有依赖使用最新版本的Axios启用Node.js的--disable-protodelete选项加强云元数据服务的安全配置建立持续的漏洞监控和响应机制可直接落地的交付物1. 快速检测脚本将以下代码保存为check-axios-vulnerability.js在项目根目录运行const{execSync}require(child_process);console.log(正在检测项目中的Axios版本...);console.log();try{constoutputexecSync(npm ls axios --all,{encoding:utf8});constversionsoutput.match(/axios(\d\.\d\.\d)/g);if(!versions){console.log(✅ 项目中没有使用Axios);process.exit(0);}constuniqueVersions[...newSet(versions)];constvulnerableVersions[];uniqueVersions.forEach(version{constvversion.replace(axios,);const[major,minor,patch]v.split(.).map(Number);if((major1minor15)||(major0minor31)){vulnerableVersions.push(v);}});if(vulnerableVersions.length0){console.log(✅ 所有Axios版本均已修复);}else{console.log(❌ 发现受影响的Axios版本);vulnerableVersions.forEach(vconsole.log(-${v}));console.log(\n请立即升级到1.15.0或0.31.0及更高版本);console.log(建议在package.json中添加overrides强制所有依赖使用最新版本);}}catch(error){console.error(检测失败,error.message);console.log(请确保已安装npm并在项目根目录运行此脚本);}2. 修复检查清单升级直接依赖的Axios到最新版本运行检测脚本检查所有间接依赖在package.json中添加overrides强制升级执行npm install更新依赖全面测试应用功能是否正常运行启用Node.js的--disable-protodelete选项检查云元数据服务的安全配置更新项目的SBOM文档配置漏洞监控告警3. Ansible批量修复脚本将以下内容保存为fix-axios-cve-2026-40175.yml可批量修复多台服务器上的Node.js项目----name:批量修复CVE-2026-40175 Axios漏洞hosts:allbecome:yesvars:axios_fixed_version:^1.15.0project_paths:-/opt/app1-/opt/app2-/var/www/apirestart_services:-app1.service-app2.service-api.servicetasks:-name:检查Node.js和npm是否安装command:npm--versionregister:npm_versionignore_errors:yes-name:跳过未安装npm的主机meta:end_hostwhen:npm_version.rc!0-name:遍历所有项目目录include_tasks:fix_single_project.ymlloop:{{ project_paths }}loop_control:loop_var:project_path-name:重启应用服务systemd:name:{{ item }}state:restarteddaemon_reload:yesloop:{{ restart_services }}when:item is defined and item!ignore_errors:yes-name:生成修复报告copy:content:|CVE-2026-40175修复报告 修复时间{{ ansible_date_time.iso8601 }} 主机{{ ansible_hostname }} 修复的项目 {% for path in project_paths %} - {{ path }} {% endfor %} 重启的服务 {% for service in restart_services %} - {{ service }} {% endfor %}dest:/var/log/cve-2026-40175-fix.log创建fix_single_project.yml文件----name:检查项目目录是否存在stat:path:{{ project_path }}/package.jsonregister:package_json-name:跳过不存在的项目meta:end_playwhen:not package_json.stat.exists-name:备份原始package.jsoncopy:src:{{ project_path }}/package.jsondest:{{ project_path }}/package.json.bak.{{ ansible_date_time.epoch }}remote_src:yes-name:检查是否已存在overrides配置command:jq .overrides {{project_path}}/package.jsonregister:overrides_existsignore_errors:yeschanged_when:false-name:添加或更新overrides配置command:jq .overrides.axios {{ axios_fixed_version }} {{ project_path }}/package.json {{ project_path }}/package.json.tmpwhen:overrides_exists.stdout null or overrides_exists.rc!0-name:合并现有overrides配置command:jq .overrides | . {axios: {{ axios_fixed_version }}} {{ project_path }}/package.json {{ project_path }}/package.json.tmpwhen:overrides_exists.stdout!null and overrides_exists.rc 0-name:替换原始package.jsoncommand:mv {{project_path}}/package.json.tmp {{project_path}}/package.json-name:更新依赖command:npm installargs:chdir:{{ project_path }}register:npm_install_resultchanged_when:added in npm_install_result.stdout or updated in npm_install_result.stdout-name:验证Axios版本command:npm ls axiosargs:chdir:{{ project_path }}register:axios_version_checkchanged_when:false-name:打印验证结果debug:msg:{{ project_path }} 中的Axios版本{{ axios_version_check.stdout_lines }}使用方法# 编辑hosts文件添加目标服务器# 运行修复脚本ansible-playbook-ihosts fix-axios-cve-2026-40175.yml