npm 上未发布的模块:攻击者可以利用他们以前的恶名吗?

信息安全 节点.js npm 包管理器
2021-09-02 02:53:25

本周早些时候,Azer Koçulu 决定npm ( Node.js的默认包管理器)取消发布他的模块他总共发表了273 个模块

一些主要的模块,比如 Babel 和 React,依赖于其中之一:left-pad,并且很多 npm 安装开始失败,因为找不到该模块。原始模块很快被 Cameron Westland 重新发布为 1.0.0 版本,因为 npm 允许重新发布废弃的包名称,只要它们不使用相同的版本号。

然后npm 工作人员决定重新发布原始版本,因为他们仍然观察到许多错误。

不过,有人可能比 Cameron 更快,他可能上传了恶意脚本而不是原始脚本。由于包没有签名,恶意脚本可能已经被下载并执行了数千次。

npm 是否有任何机制可以防止攻击者利用未发布模块的恶名?

1个回答

可以将恶意代码推送到 NPM 吗?

最肯定的。如果一个包被破坏(或发布了一个新包),安装和使用该包提供的任何代码都可以执行。因此,例如,如果他们在 node.js 上下文中运行它,则攻击可以访问许多机器级别的功能,例如文件系统、系统信息、文件执行、进程等。这就像将攻击者代码放到在出口退回。因此,一旦他们require('bad-package')执行代码。更糟糕的是,它可能像安装模块一样简单。他们可以在包的清单中指定一个预安装脚本并立即运行该脚本。

恶意代码是否被推送到 NPM?

最肯定的是。2015 年 1 月 26 日,一个名为的包rimrafall被发布到 NPM。其目的是提高对该问题的认识。该软件包将运行一个预安装挂钩,以便在安装后立即rm -rf /*执行。Rimrafall 在 2 小时内被删除,但可以在Github上找到。

开发人员能否保证自己和用户的安全?

作为开发人员,唯一接近可靠的预防方法是将package.json中的版本锁定到已知安全的版本。通常会实施版本锁定以确保仅使用已知的工作依赖项,并且未经测试的依赖项更新不会破坏任何内容。但同样可以用来抵御攻击者版本。正如您所提到的,您不能重新发布特定版本的文件。通过在依赖项中设置确切的版本,您的应用程序将只下载此版本。如果攻击者要控制软件包,他们只能将恶意代码推送给后续软件包的用户。我说“接近可靠”是因为如果攻击者要破坏 NPM 的服务器,他们可以将以前的版本更改为他们想要的任何版本。

--ignore-scripts此外,您可以在安装时使用该标志来防止预安装脚本攻击。这将使您有机会安装但在运行它之前查看它的代码。(除非软件包包含本机二进制文件。)在安装之前,您可以通过运行来检查此类脚本npm show $module scripts如果您不想使用 NPM 来查看脚本,您可以直接在http://registry.npmjs.org/MODULENAME/-/MODULENAME-VERSION.tgz.

NPM 是否会阻止某人接管未发布的包?

是和不是。一旦未发布,就会保留包名称以防止立即滥用。但是,如果您从 NPM 请求它,它仍然可以获得。理论上,简单的社会工程可以绕过审查过程,并将包名交到攻击者手中。未发布包的消息如下:

这个包名目前没有被使用,但以前被一个流行的包占用。为避免恶意使用,npm 会挂在包名上,但很松散,如果您需要,我们可能会将其提供给您。

您可以通过联系 support@npmjs.com 并请求名称来采用此包。

综上所述

所以最后,攻击者可以利用未发布的包吗?是的,如果错误的人迅速取得所有权,那么他们就不会用他们的代码推送包更新。这将危及任何下载该软件包的最新版本或安装/更新没有版本锁定其依赖项的项目的人。

编辑:请记住,您的依赖项可以有依赖项。因此,虽然依赖项本身看起来是安全的,但请确保它没有加载到它自己的不安全依赖项中。