小心!Axios这个漏洞会让Nodejs服务直接崩溃
如果你用Nodejs写后端服务,大概率用过axios这个库。它用来发HTTP请求,简单好用。但最近axios爆出一个漏洞,能让你的服务瞬间挂掉。攻击者只需要发一段特殊的数据,你的程序就直接崩溃。
这不是吓唬人。这个漏洞真实存在,而且影响范围很广。今天我们就来看看这个漏洞是怎么回事,怎么复现,以及如何解决。
漏洞出在哪里
漏洞在axios的mergeConfig函数里。这个函数用来合并请求配置。比如你设置了一个全局配置,发请求时又传了新的配置,它就把两个配置合并到一起。
问题出在lib/core/mergeConfig.js文件,第98到101行。代码大致是这样:
utils.forEach(Object.keys({ ...config1, ...config2 }), function computeConfigValue(prop) {
const merge = mergeMap[prop] || mergeDeepProperties;
const configValue = merge(config1[prop], config2[prop], prop);
(utils.isUndefined(configValue) && merge !== mergeDirectKeys) || (config[prop] = configValue);
});这段代码看起来没问题。但问题出在Object.keys这里。如果配置对象里有一个叫__proto__的属性,Object.keys会把__proto__也遍历出来。
__proto__是JavaScript里一个特殊的属性。它指向对象的原型。正常情况下,你遍历对象是拿不到__proto__的。但如果你用JSON.parse解析一段特殊构造的字符串,__proto__就会变成一个普通属性,可以被遍历到。
当代码执行到mergeMap['proto']时,因为mergeMap里没有__proto__这个键,JavaScript就去原型链上找。结果找到了Object.prototype。所以merge变量拿到的不是函数,而是Object.prototype。后面再调用merge(...)就会报错,说merge不是一个函数。程序直接崩溃。
漏洞怎么复现
这个漏洞复现起来很简单。安装axios,然后运行下面这段代码:
import axios from "axios";
const maliciousConfig = JSON.parse('{"__proto__": {"x": 1}}');
await axios.get("https://httpbin.org/get", maliciousConfig);运行后程序马上崩溃,报错信息是:
TypeError: merge is not a function
at computeConfigValue (lib/core/mergeConfig.js:100:25)
at Object.forEach (lib/utils.js:280:10)
at mergeConfig (lib/core/mergeConfig.js:98:9)我们对比一下不同配置的运行结果:
| 测试场景 | 配置 | 结果 |
|---|---|---|
| 正常配置 | {"timeout": 5000} | 正常运行 |
| 恶意配置 | JSON.parse('{"proto": {"x": 1}}') | 直接崩溃 |
| 普通嵌套对象 | {"headers": {"X-Test": "value"}} | 正常运行 |
可以看到,只有恶意配置会导致崩溃。
哪些场景会受影响
这个漏洞影响的是Nodejs后端服务。前端浏览器环境不会受影响,因为崩溃的是服务端。
如果你的服务满足下面两个条件,就存在风险:
接收前端或用户传过来的JSON数据
把解析后的对象直接传给axios当配置
举个例子。你写了一个接口,用户通过POST传一些参数过来。你用JSON.parse解析后,把这些参数当成axios的配置,去请求另一个服务。这时候攻击者就可以构造恶意数据,让你的服务崩溃。
攻击者只需要传:
{"__proto__": {"x": 1}}你的服务处理到这个数据,就挂了。
漏洞影响范围
这个漏洞属于拒绝服务漏洞。攻击者无法拿到你的数据,也无法执行任意代码。但他可以让你的服务无法正常提供服务。如果你的服务是核心业务,那影响就很大。
受影响的版本是axios 1.x系列。官方已经在最新版本修复了这个问题。
怎么修复
修复方法很简单,就两步:
第一步,升级axios版本。
去你的项目里查看package.json,看axios版本是多少。如果是1.x版本,直接升级到最新版。运行:
npm install axios@latest或者
yarn add axios@latest第二步,重启服务。
升级完依赖后,重启你的Nodejs服务,让新版本生效。
如果你暂时不能升级,也可以用其他方法规避。比如在传给axios之前,先对配置对象做处理,把__proto__属性删掉。但最稳妥的办法还是升级。
开发时要注意什么
这个漏洞提醒我们几件事。
第一,不要相信用户输入。任何从外面传进来的数据都可能有问题。用之前要校验、过滤。
第二,不要把用户输入直接传给底层库。像axios配置这种,最好自己先处理一遍,去掉那些不该有的属性。
第三,依赖库要及时更新。安全漏洞每天都在被发现,及时更新是保护自己最简单的方式。
总结
axios这个漏洞影响范围广,复现简单,危害也不小。但修复起来也很容易,升级到最新版就行。如果你在用axios写Nodejs服务,赶紧去检查一下版本。如果是1.x,马上升级。几分钟的事,能帮你省去后面的大麻烦。
本文内容仅供个人学习、研究或参考使用,不构成任何形式的决策建议、专业指导或法律依据。未经授权,禁止任何单位或个人以商业售卖、虚假宣传、侵权传播等非学习研究目的使用本文内容。如需分享或转载,请保留原文来源信息,不得篡改、删减内容或侵犯相关权益。感谢您的理解与支持!