【问题标题】:How to run user-submitted scripts securely in a node.js sandbox?如何在 node.js 沙箱中安全地运行用户提交的脚本?
【发布时间】:2023-03-19 08:59:01
【问题描述】:

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

vm.runInNewContext(userScript, {}) 是一个诱人的起点……但那里似乎有known issues

sandbox module 看起来很有趣,但也使用了runInNewContext(),所以我对此有点怀疑。

【问题讨论】:

  • 我推荐使用vm,因为它是节点核心的一部分。由于节点核心倾向于修复其错误,因此假设问题将得到修复
  • @Raynos 这不是错误。文档说它仅适用于已知良好的代码。
  • @thejh - 是的,但 API 确实倾向于相当合理的信念,即代码在完全不同的上下文中执行,这意味着所述代码不应该能够访问当前上下文。我希望 API 的 intent 正是如此 - 提供一个运行脚本的沙箱。所以......我认为可以证明这只是一个有据可查的错误。 :)
  • 这能回答你的问题吗? How to run untrusted code serverside?

标签: javascript node.js v8


【解决方案1】:

a newer module on github called vm2 解决了其中一些问题,尤其是在 Node.JS 应用程序中。也许这会帮助其他人找到它,就像我刚刚所做的那样。

【讨论】:

    【解决方案2】:

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

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

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

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

    • 代码已过时,已有 7 个月未更新。
    • node 中的子进程模块已经提供了您需要的大部分功能,尤其是child_process.fork()
    • child_process.fork 提供的 IPC 通道可能性能更好。

    为了提高安全性,您还可以考虑使用setuid-sandbox。这是谷歌浏览器用来阻止标签进程访问文件系统的代码。您必须制作一个原生模块,但这个 example 似乎很简单。

    【讨论】:

    • vm 模块中的方法现在支持timeout 参数,可以让您安全地执行while(true) {}。它显然没有解决安全问题,但确实解决了无限循环。
    • @AndrewPaprocki 你能链接到显示超时的文档吗?
    • 这个答案很好。不过,我想指出另一个类似的问题(最近的),这可能对有同样问题的人有帮助:stackoverflow.com/questions/17513212/…
    猜你喜欢
    • 2013-07-04
    • 1970-01-01
    • 1970-01-01
    • 2010-11-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多