Node.js 中的 devDependencies 可以利用吗?

信息安全 脆弱性 更新 包管理器 图书馆 npm
2021-09-08 14:55:04

我很清楚,最好的方法是更新任何依赖项,无论它是开发依赖项还是运行时/生产依赖项。

但是从研究的角度来看,我想知道开发依赖项中的漏洞是否有机会被利用。

让我们以 JavaScript 为例,它npm用作中央包注册表。

根据定义,devDependencies(开发依赖项)应包含在开发期间使用或用于构建捆绑包的包。例如,ESlint(linter)、Mocha(测试框架)和Webpack(模块捆绑器)。

在开发阶段是否可以利用这些开发依赖项或其他相关开发依赖项中的漏洞?如果是,那么有什么例子吗?

注意:其他相关问题的答案提到供应链攻击。但是,据我所知,供应链攻击的关键在于将恶意代码注入到开发依赖中,例如著名的 SolarWinds 攻击。

我的问题是不同的,因为在这种情况下,我问的是开发依赖本身是否可以包含可能被攻击者注入的恶意代码,这样开发依赖就会变成恶意的。

我想重复一遍:

我要问的是攻击者是否可以利用“benigh”开发依赖的漏洞来破坏我正在开发阶段开发的软件。

任何现实世界的例子都会很棒。

我还想知道可能的缓解方案。

2个回答

它取决于漏洞和威胁环境(对于每个组件都是如此,而不仅仅是开发组件)。以下是一些(通用)示例:

  1. 从指定位置获取外部脚本并执行它的工具。漏洞:库通过 HTTPS 获取脚本,但不验证证书。可利用性: 的,中间人网络攻击者可以用恶意脚本替换预期的、受信任的脚本,以在您的机器上执行代码。
  2. 一种应用程序框架,当启动调试时,在一个端口上启动应用程序并在另一个端口上启动调试服务。调试服务可用于控制程序执行。漏洞:调试服务监听所有接口且未经身份验证。Exploitable: YES,网络攻击者(如果没有被防火墙阻止)或同一主机上的低权限用户可以连接到调试服务器以控制应用程序,从而导致任意代码执行。
  3. 与上面相同,但调试接口是本地(Unix)套接字。漏洞:套接字是全局可访问的。可利用性: 很可能,因为您系统上的任何其他用户(或以其他用户身份运行的进程)都可以使用本地套接字来像您一样执行代码。但是,如果机器是单用户的(没有其他用户运行代码)并且服务器没有比其他任何东西更高的权限(EoP 没有机会),那么在这种情况下就没有关系了。
  4. 一种对可发布文件进行加密签名的工具。漏洞:该工具错误地截断长度超过 4096 位的签名,导致签名不安全和不正确。可利用: 不太可能,因为 RSA 密钥长度超过 4096 位在实践中并不常见,因为 4096 位 RSA 密钥已经非常安全。此外,如果您确实使用了一个,您可能会注意到签名无法验证......但如果您没有,这可能会给您发布的文件的使用者(可能是您自己的公司)带来问题,如果他们无法验证文件和/或他们是否使用验证文件的验证器(由于执行相同的截断),但截断使得修改文件更容易而不会使签名无效。
  5. 从模板生成文件的工具。漏洞:该工具可能会错误地将生成的文件相对于系统根目录而不是当前目录放置。可利用: 不太可能,因为生成的文件意外覆盖任何内容的可能性非常低,除非它们的目录结构类似于系统根目录,并且该工具可能不会以提升的权限运行,因此无论如何都无法覆盖大多数文件。出现的恶意依赖 良性可以利用这一点,导致覆盖例如你的 ~/.ssh/authorized_keys 具有恶意值(如果易受攻击的工具与它一起使用)而不直接包含恶意代码本身,但这样的攻击是非常不可能的(并且在技术上是供应链攻击,只是偷偷地利用另一个工具的错误)。
  6. 一个工具,除其他外,它可以根据您的提交消息更新 Jira 工作项。漏洞: Jira 集成首先为每个请求尝试 HTTP,只有在重定向后才升级到 HTTPS(就像 Jira 通常那样)。可利用性: 取决于您是否使用 Jira 如果您这样做,网络攻击者可以窃取您的 Jira 信誉并像您一样进行更改。但是,如果不是,则此漏洞与您的环境无关。
  7. 一种通过 HTTPS 将静态分析结果上传到服务器的工具。漏洞:该工具打包了一个版本的 OpenSSL,该版本在用作 TLS 服务器时包含拒绝服务漏洞。Exploitable: ,该工具不充当 TLS 服务器,仅充当 TLS 客户端,因此该漏洞与其用例无关。

在运行npm start命令和开发ENV设置为开发或运行一个特殊的命令(例如npm run dev,在开发是一个特殊的脚本中指定其启动本地开发环境package.json),其执行devDependencies指定package.json当然,在某些情况下,首先由用户决定是否包含所需的文件,但也有一些例外,例如假的(模拟的)API、Angular 中使用的本地主机服务器(您使用 运行它ng serve,实际上默认情况下甚至不包含 self-签名的 SSL 证书)等等。现在真正的危险是 Bash/PowerShell/Batch 文件和二进制文件也可以以这种方式执行,这真是太糟糕了!

现在到问题的主要部分——它可能造成什么危害?由于它执行任何任意代码,而忽略了 V8(在 2021 年仍被认为是最安全的 JavaScript 引擎)包含一个出色的沙箱这一事实,谷歌为此付出了很多工作来确保安全,并且在没有任何代码审查的情况下盲目运行,这可能意味着以下之一:

  • 上传并泄露您的整个源代码
  • 销毁你的源代码
  • 由于它具有文件系统访问权限,因此可能会弄乱您的文件系统,并且可能在理论上扩展,例如安装 rootkit
  • 它可以嗅探您的本地网络流量,现在通常是加密的
  • 它可以承载一个邪恶的 AP 双胞胎
  • 木马、蠕虫、加密矿工等
  • 它可以读取您的网络活动
  • 它可能会弄乱您的数据包,发送您不想要的数据包
  • 弄乱您的证书,伪造它们等
  • 恶意 linter 是否可以与 snyk.io 做相反的事情 - 将漏洞插入/建议在您的应用程序中构建漏洞,从而在生产中制作易受攻击的应用程序/API
  • 理论上甚至会损坏您的硬件
  • 混淆自身以隐藏恶意代码
  • 这些和更多的组合......

...以及恶意软件通常具有的其他可能性... Security StackExchange 充满了其他关于它可能会如何被滥用的建议。

没有内置的权限系统或类似的东西,所以显然可能性几乎是无穷无尽的......

更现实的例子包括:易受攻击的解析器,它可以读取 RCE 等,糟糕的加密,很容易被“黑客攻击”(这存在于本机库加密中,如果我仍然在加密中并且曾经有警告文档不使用某些方法),请参阅下面的漏洞历史记录。

现在,本地开发服务器呢?它们不能被来自外部的机器人(即万维网)抓取吗?这取决于你的防火墙、路由器和你的本地服务器实现。通常本地开发服务器使用 localhost 接口(如在 Windows 中所做的那样)或 127.0.0.1 本地 IP,只能在 LAN 内部访问。我已经看到一些业余制作的本地开发服务器在 Unix 上使用 0.0.0.0 接口,如果您对 World Wild Web 开放,这将是一个很大的麻烦,这意味着您的 API 可能会被暴力破解,并且所有复杂的 API(同样取决于您的API)为您的机器打开了恶意软件的大门(我当然是在暗示 API 被发现并且它具有写入和执行(通常通过 LFI 等漏洞)的可能性)。

在模块中审查 JavaScript 有多难?好吧,现在混淆和最小化工具非常先进,并且有专门从事该领域的公司,据说他们承诺您的 JavaScript 不会通过中等努力进行逆向工程。如果你想要一个很好的例子,我总是指向一个流行的 xkcd 漫画,其中包含用于右键菜单的混淆 JavaScript https://xkcd.com/1975/

此外,还有产生恶意服务人员和其他恶作剧的危险。

如果你想在开发和生产中获得最大的安全性并想使用 JavaScript,我建议你研究一下 Deno,它实际上是由最初开发 Node.js 的 Ryan Dahl 开发的,他对自己说“嘿,我会做得更好”。他制作了一个名为“我对 Node.js 感到遗憾的 10 件事”的视频。视频链接在这里:https ://www.youtube.com/watch?v=M3BM9TB -8yA 从大约。6:13 在视频中,开发人员承认 Node.js 主事件循环可以访问各种系统调用。由于 Node.js 通常以 admin/root 身份运行,这可能导致上述所有可能性。

如果您想查看更安全的基础架构,请查看时间戳 18:59 的视频。

显然npm audit没有进行实际的代码分析,只显示报告的漏洞,但这并不能解决任何问题。另一方面,只要模块没有被混淆,GitHub 安全机器人和 Snyk.io 机器人确实有可能检测到此类漏洞。

我发现极有可能发生的是,以下操作肯定没有限制:

  • 劫持require()调用,就像它是由 babel、TypeScript 组件等善意的软件完成的
  • 令人惊讶的是,它实际上可以覆盖核心模块。

我是一名铁杆程序员,我能做什么?

我很高兴你问。Node.js API(或核心模块,随便你怎么称呼)包含一个 VM API。有关更多信息,请查看此文档链接您可以为您的代码获取 V8 Sandbox 的功能,但正如链接中所述,Node.js 的维护者建议不要在其中运行不受信任的代码。

开发包中的漏洞历史

关于第三方依赖的一般 hkcert 建议