数百万次下载的Node.js模块具有一个安全漏洞,攻击者可以利用该漏洞在服务器上执行拒绝服务(DoS)攻击或获得完全的远程Shell访问。
漏洞分配为 CVE-2020-7699,位于“ express-fileupload ” npm组件中,该组件已从npm 下载至少730万次。
估算是保守的,因为它没有考虑从GitHub,镜像网站和其他克隆存储库的下载。
由于该语言的基本性质,这种类型的漏洞(称为“原型污染”)通常会在JavaScript(JS)代码中发生。由于JS是基于原型的语言,因此该语言中的每个对象,函数和数据结构都具有固有的“原型”属性,可以通过“ __proto__”增变器对其进行修改。
修改现有代码的能力是一项预期功能,可以轻松扩展具有更多属性和方法的现有对象。
诸如此类的原型攻击通过将不兼容类型 的对象注入到现有对象中来引发错误,从而利用了这种“设计缺陷” ,从而导致了拒绝服务(DoS),如果不是远程外壳访问,至少会导致拒绝服务。
利用原型
由于express-fileupload提供的“ parseNested”功能,实际的攻击成为可能。启用后,“ parseNested”选项负责将上传的JSON数据“展平”到嵌套对象中。
发现此漏洞的安全研究人员Posix在博客文章中解释说:“ express-fileupload模块提供了几个用于在[Node.js]应用程序中上载和管理文件的选项。其中,parseNested make参数变平了。”
例如,如果您的应用程序使用“ express-fileupload”模块来促进文件上传,并且“ parseNested”选项设置为“ true”,则这将指示服务器端应用程序开始将接收到的数据展平为嵌套的JSON对象。
下图说明了此“ parseNested”选项。

来源: GitHub
当在“ Content-Disposition” HTTP标头中提供简单的有效负载时,攻击者可以提供“ __proto __。toString”值来触发攻击。

来源: GitHub
回想一下,“ __ proto__”增变器会影响所有 JS对象和结构所继承的JavaScript的“ Prototype”属性 。
本质上,此处显示的HTTP请求将覆盖并破坏 代码中存在的每个对象的内置“ toString”方法 。
研究人员说:“如果 Object.prototype.toString
可能被污染,将导致错误,对于每一个请求,express [sic]总是返回500错误。”
通过反向Shell远程执行代码
研究人员描述了此漏洞利用方法的更为复杂的变体,它使攻击者可以在易受攻击的系统上获得外壳。但是,这种利用很大程度上取决于是否使用易受攻击的“ express-fileupload”版本的应用程序还使用了模板引擎EJS(嵌入式JavaScript模板)。
假设您的应用程序使用EJS解析上传的数据,而未进行其他检查。然后,攻击者可以发送覆盖EJS的“ outputFunctionName”选项的HTTP请求。

(来源:Posix)
上面显示的有效负载利用了express-fileupload中的原型污染,并指示EJS(应在使用中)启动Node.js“ child_process”。这个新启动的过程进一步产生了攻击者计算机的反向外壳。
建立连接后,攻击者现在可以在受感染的服务器上执行任意代码。

(来源:Posix)
并非所有安装都受影响
但是,该漏洞可能不会影响所有用户。只有那些启用了“ parseNested”选项的应用程序才容易受到此原型污染漏洞的攻击。
此外,要实现完整的外壳程序访问和远程执行代码,还必须具备另一个库(例如EJS)以及易受攻击的express-fileupload。值得注意的是,EJS并不是唯一可以进行shell访问的库。
Posix表示 ,这些攻击不仅影响EJS,“我的文章介绍了如何通过EJS获取外壳。但是因为原型污染可以改变各种环境的流程,所以简单地添加一些引用的模块可以为攻击者创造许多可能性。”
在收到研究人员报告的几个小时内 ,“ express-fileupload”修复了该漏洞,用户应考虑从npm获取最新的修补版本1.1.9。
*编译:Domino
*来自:bleepingcomputer