小心!Axios这个漏洞会让Nodejs服务直接崩溃

摘要:如果你用Nodejs写后端服务,大概率用过axios这个库。它用来发HTTP请求,简单好用。但最近axios爆出一个漏洞,能让你的服务瞬间挂掉。攻击者只需要发一段特殊的数据,你的程序就直接崩溃。

如果你用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);

运行后程序马上崩溃,报错信息是:

text
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后端服务。前端浏览器环境不会受影响,因为崩溃的是服务端。

如果你的服务满足下面两个条件,就存在风险:

  1. 接收前端或用户传过来的JSON数据

  2. 把解析后的对象直接传给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,马上升级。几分钟的事,能帮你省去后面的大麻烦。

本文内容仅供个人学习、研究或参考使用,不构成任何形式的决策建议、专业指导或法律依据。未经授权,禁止任何单位或个人以商业售卖、虚假宣传、侵权传播等非学习研究目的使用本文内容。如需分享或转载,请保留原文来源信息,不得篡改、删减内容或侵犯相关权益。感谢您的理解与支持!

链接: https://shenqiku.cn/article/FLY_13331