请立即停止使用 node-open 模块

3,719 阅读2分钟

node-open 是一个 npm 包,可以使用系统默认关联的方式打开 uri 和本地文件。从 commit 日志和 npm 发布时间来看,node-open 包似乎已经停止维护好几年了:

  • https://www.npmjs.com/package/open
  • https://github.com/pwnall/node-open

另外作者的用户名 pwnall 让我一度误认为是 pwnallthethings 的马甲,居然还是位 Chrome 的开发成员。

pwnall

这个包的源码非常短,问题很明显: https://github.com/pwnall/node-open/blob/master/lib/open.js#L58

var exec = require('child_process').exec

...

return exec(opener + ' "' + escape(target) + '"', callback);

...

function escape(s) {
  return s.replace(/"/g, '\\\"');
}

虽然用了所谓的 escape 函数把双引号闭合了回去,但是这毕竟是 child_process.exec,是支持 shell 语法的。例如在 mac 系统下即可在 url 中使用 反引号、\$()\${} 等特殊字符执行命令、获取环境变量。真是一股浓浓的 Damn Vulnerable Web Application 风味,还是入门级的难度。使用 node-open 打开外部不受信任的 url 等同于 php 里直接拼接 system 的参数。

那么他在真实环境中的影响有多大呢?

这是 2018 年 2 月 27 日的统计数据:

Stats

  • 28,381 downloads in the last day
  • 476,031 downloads in the last week
  • 1,925,595 downloads in the last month

Dependents (1652)

虽然下载量和依赖量很大,但并不能说明这就是一个影响范围很大的安全问题——child_process 这个模块每一个 node 发行包都有,就直接搞个大新闻说 Node.js 不能用?

使用系统关联工具打开 url 的场景多适用于桌面应用,因此不大可能会使用这个模块。但有一些桌面工作流可能会出现使用 RPC 接口的情况。

Macaw 是一款所见即所得网页编辑器,支持在浏览器中实时预览(livereload):http://macaw.co/

在 Macaw.app/Contents/www/thirdparty/preview/index.js 中打开了两个服务器:

// defaul ports for server and LR
var defaults = { livereload: 15729, port: 5353 };

一个是 livereload 的 WebSocket,另一个是 JSON RPC 的服务。有一个支持传入参数拼接后打开浏览器的接口:

//open default browser
app.get('/openbrowser/:path/:file', function(req, res) {
  var file = req.param('file');
  var path = req.param('path');

  var callback = function() {
    open('http://localhost:'+app.get('port')+'/'+file);
  };

  setWatch(path, callback);

  // return 200 OK
  res.send(200);
});

这里的 file 参数由外部 HTTP 请求传入,直接拼接到了 url 中。简单地使用 shell 脚本即可被执行:

import requests
requests.get('http://192.168.1.100:5353/openbrowser/aaa/`echo 1>${PWD}tmp${PWD}1`')

安装了这个编辑器的前端开发者万万没想到,这个软件居然就这样成了一个赤裸裸的后门。

Macaw 对此问题的答复是,由于这款软件已经被 InVision 收购,1.6 将成为最终版本,不再修复 bug。

鉴于 node-open 这个显而易见的问题和停止维护的状态,请考虑使用替代方案。例如 opn:https://www.npmjs.com/package/opn