javascript 如何在 node.js 沙箱中安全地运行用户提交的脚本?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7446729/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to run user-submitted scripts securely in a node.js sandbox?
提问by broofa
What are the options for running (possibly malicious) user-submitted scripts in node.js, securely? I.e. in an environment that prevents code from accessing sensitive data and APIs?
在 node.js 中安全运行(可能是恶意的)用户提交的脚本有哪些选项?即在阻止代码访问敏感数据和 API 的环境中?
vm.runInNewContext(userScript, {})
is a tempting starting point... but it seems like there are known issuesthere.
vm.runInNewContext(userScript, {})
是一个诱人的起点……但似乎那里存在已知问题。
The sandbox modulelooks interesting, but uses runInNewContext()
as well so I'm a bit leery of it.
在沙箱模块看起来很有趣,但使用runInNewContext()
也使我的有点持怀疑态度。
采纳答案by Laurent Perrin
You should always run untrusted code in a separate process, which is exactly what the sandbox module does. A simple reason is that vm.runInNewContext('while(true){}', {})
will freeze node.
您应该始终在单独的进程中运行不受信任的代码,这正是沙箱模块所做的。一个简单的原因是vm.runInNewContext('while(true){}', {})
会冻结节点。
It starts by spawning a separate process, which will later send the result serialized to JSON on its stdout. The parent process continues executing regardless of what the child does and can trigger a timeout.
它首先生成一个单独的进程,该进程稍后将在其标准输出上发送序列化为 JSON 的结果。无论子进程做什么,父进程都会继续执行,并且可以触发超时。
The untrusted code is then wrapped in a closure with strict mode(in regular JavaScript, you can use arguments.callee.caller
to access data outside of your scope). Finally, a very limited global
object is passed to prevent access to node's API. The untrusted code can only do basic computation and has no access to files or sockets.
然后将不受信任的代码封装在一个严格模式的闭包中(在常规 JavaScript 中,您可以使用它arguments.callee.caller
来访问范围之外的数据)。最后,global
传递了一个非常有限的对象以防止访问节点的 API。不受信任的代码只能进行基本计算,无法访问文件或套接字。
While you should read sandbox's code as an inspiration, I wouldn't recommend using it as is:
虽然您应该阅读沙箱的代码作为灵感,但我不建议按原样使用它:
- The code is getting old and hasn't been updated for 7 months.
- The Child Process module in node already provides most of the features you need, especially child_process.fork().
- The IPC channel provided by child_process.fork probably has better performances.
- 代码老了,7个月没更新了。
- node 中的 Child Process 模块已经提供了您需要的大部分功能,尤其是child_process.fork()。
- child_process.fork 提供的 IPC 通道可能有更好的性能。
For increased security, you could also consider using setuid-sandbox. It's the code used by Google Chrome to prevent tab processes from accessing the file system. You would have to make a native module, but this exampleseems straightforward.
为了提高安全性,您还可以考虑使用setuid-sandbox。这是谷歌浏览器用来防止标签进程访问文件系统的代码。您必须制作一个本机模块,但这个例子看起来很简单。
回答by Alan Mimms
There is a newer module on github called vm2that addresses some of these concerns, especially in Node.JS applications. Maybe that will help some others find it, as I have just done.
github 上有一个名为 vm2 的较新模块可以解决其中的一些问题,尤其是在 Node.JS 应用程序中。也许这会帮助其他人找到它,就像我刚刚所做的那样。