可以将恶意代码推送到 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 并请求名称来采用此包。
综上所述
所以最后,攻击者可以利用未发布的包吗?是的,如果错误的人迅速取得所有权,那么他们就不会用他们的代码推送包更新。这将危及任何下载该软件包的最新版本或安装/更新没有版本锁定其依赖项的项目的人。
编辑:请记住,您的依赖项可以有依赖项。因此,虽然依赖项本身看起来是安全的,但请确保它没有加载到它自己的不安全依赖项中。