我希望能够让用户提交任意JavaScript代码,然后将其发送到Node.JS服务器,并在输出发送回多个客户端(作为JSON)之前安全执行。我想到eval
函数,但我知道这有多个安全问题(用户提交的代码将能够访问Node的File API等)。我见过一些项目,如Microsoft Web Sandbox和Google Caja,它们允许执行清理标记和脚本(用于在网站上嵌入第三方广告),但似乎这些是客户端工具,我不确定它们是否可以在Node中安全使用。
是否有一种标准方法可以在Node中沙箱并执行不受信任的JavaScript,从而获得输出。尝试做这个服务器端是错误的吗?
编辑:用户能够利用JavaScript的全部功能并不重要,事实上,最好是能够选择将哪些API提供给用户代码
编辑:我将继续使用我发现的内容进行更新。这个Sandcastle模块(bcoe/sandcastle
)似乎旨在实现我的想法。不确定它有多安全,但由于我不是太重要,我想如果尝试的话。如果我能成功地做到这一点,我会添加自己的答案。
答案 0 :(得分:10)
您可以在nodejs中使用vm.runInContext(' js代码',上下文)中的沙盒支持,在api文档中进行示例:
https://nodejs.org/api/vm.html#vm_vm_runinthiscontext_code_options
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 }
警告:正如#34; s4y&#34;它似乎被打了个瑕疵。请查看评论。
答案 1 :(得分:4)
此答案已过时,因为gf3无法防止沙箱破坏
http://gf3.github.io/sandbox/ - 它使用require('child_process')
代替require('vm')
。
答案 2 :(得分:4)
在Node.js下,您可以创建一个沙盒子进程,但是您还需要使用"use strict";
附加代码,否则可以使用arguments.callee.caller
来破坏沙箱。
不确定为什么需要将其发送到服务器,因为代码也可能在沙盒网络工作者中执行。
另请查看我的Jailed库,它简化了Node.js和Web浏览器中提到的所有内容,并提供了将一组函数导出到沙箱中的机会。
答案 3 :(得分:4)
另一种方法是使用http://github.com/patriksimek/vm2:
$ npm install vm2
然后:
const {VM} = require('vm2');
const vm = new VM();
vm.run(`1 + 1`); // => 2
如其他答案的评论中所述。
我不知道它有多安全,但它至少声称它安全地运行不受信任的代码(在其自述文件中)。到目前为止,我在其他答案中建议的解决方案中找不到任何明显的安全问题。
答案 4 :(得分:0)
根据您的使用情况,建议您也考虑使用gVisor等虚拟环境来保护沙箱。您可以找到一些信息here。