如何在 node.js 沙箱中安全地运行用户提交的脚本?

IT技术 javascript node.js v8
2021-01-27 17:30:00

在 node.js 中安全运行(可能是恶意的)用户提交的脚本有哪些选项?即在阻止代码访问敏感数据和 API 的环境中?

vm.runInNewContext(userScript, {})是一个诱人的起点……但似乎那里存在已知问题

沙箱module看起来很有趣,但使用runInNewContext()也使我的有点持怀疑态度。

2个回答

您应该始终在单独的进程中运行不受信任的代码,这正是沙箱module所做的。一个简单的原因是vm.runInNewContext('while(true){}', {})会冻结节点。

它首先生成一个单独的进程,该进程稍后将在其标准输出上发送序列化为 JSON 的结果。无论子进程做什么,父进程都会继续执行,并且可以触发超时。

然后将不受信任的代码封装在一个严格模式的闭包中(在常规 JavaScript 中,您可以使用它arguments.callee.caller来访问范围之外的数据)。最后,global传递了一个非常有限的对象以防止访问节点的 API。不受信任的代码只能进行基本计算,无法访问文件或套接字。

虽然您应该阅读沙箱的代码作为灵感,但我不建议按原样使用它:

  • 代码老了,7个月没更新了。
  • node 中的 Child Process module已经提供了您需要的大部分功能,尤其是child_process.fork()
  • child_process.fork 提供的 IPC 通道可能有更好的性能。

为了提高安全性,您还可以考虑使用setuid-sandbox这是谷歌浏览器用来防止标签进程访问文件系统的代码。您必须制作一个本机module,但这个例子看起来很简单。

这个答案非常好。不过,我想指出另一个类似的问题(最近的),它可能对遇到同样问题的人有所帮助:stackoverflow.com/questions/17513212/...
2021-03-22 17:30:00
vmmodule中的方法现在支持一个timeout参数,可以让您安全地执行while(true) {}. 它显然没有解决安全问题,但确实解决了无限循环。
2021-03-24 17:30:00
@AndrewPaprocki 你能链接到显示超时的文档吗?
2021-04-05 17:30:00

github 上一个名为 vm2 的较新module可以解决其中的一些问题,尤其是在 Node.JS 应用程序中。也许这会帮助其他人找到它,就像我刚刚所做的那样。