关于node.js:安全沙箱并执行用户提交的JavaScript?

Safely sandbox and execute user submitted JavaScript?

我希望能够让用户提交任意JavaScript代码,然后将其发送到Node.JS服务器并安全地执行,然后再将输出发送回多个客户端(如JSON)。我想到了eval函数,但是我知道这有多个安全问题(用户提交的代码将能够访问Node的File API等)。我已经看到了一些项目,例如Microsoft Web Sandbox和Google Caja,它们允许执行经过清理的标记和脚本(用于在网站上嵌入第三方广告),但是似乎这些都是客户端工具,我不确定它们是否可以在Node中安全使用。

有没有一种标准的方法来沙盒化并在Node中执行不受信任的JavaScript,以获取输出。尝试在服务器端进行操作是错误的吗?

编辑:用户能否利用JavaScript的全部功能并不重要,实际上最好能够选择要提供给用户代码的API。

编辑:我将继续并用我发现的内容进行更新。这个Sandcastle模块(bcoe/sandcastle)似乎旨在实现我的想法。不知道它的安全性如何,但是由于我并没有那么重要,我想我会尝试的。如果能够成功完成,我将添加自己的答案。


您可以将node.js中的沙箱支持与vm.runInContext('js code',context),api文档中的示例结合使用:

https://nodejs.org/api/vm.html#vm_vm_runinthiscontext_code_options

1
2
3
4
5
6
7
8
9
10
11
12
const util = require('util');
const vm = require('vm');

const sandbox = { globalVar: 1 };
vm.createContext(sandbox);

for (var i = 0; i < 10; ++i) {
    vm.runInContext('globalVar *= 2;', sandbox);
}
console.log(util.inspect(sandbox));

// { globalVar: 1024 }

警告:正如" s4y"所指出的那样,它似乎存在缺陷。请查看评论。


一种替代方法是使用http://github.com/patriksimek/vm2:

1
$ npm install vm2

然后:

1
2
3
4
const {VM} = require('vm2');
const vm = new VM();

vm.run(`1 + 1`);  // => 2

如其他答案的评论中所述。

我不知道它的安全性,但是它至少声称它安全地运行了不受信任的代码(在其自述文件中)。就这里其他答案中提出的解决方案而言,我找不到任何明显的安全问题。


在Node.js下,您可以创建一个沙盒子进程,但是您还需要在代码后附加"use strict";,否则可以通过arguments.callee.caller破坏沙盒。

不确定为什么需要将其发送到服务器,因为代码也可能在沙盒网络工作人员中执行。

还要看看我的Jailed库,它简化了刚才提到的Node.js和Web浏览器的所有操作,并且还提供了将一组函数导出到沙箱的机会。


由于gf3无法提供防止沙箱损坏的保护,因此此答案已过时

http://gf3.github.io/sandbox/-它使用require('child_process')而不是require('vm')


根据您的使用情况,建议您也考虑使用gVisor等虚拟环境保护沙箱。您可以在这里找到一些信息。