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)似乎旨在实现我的想法。不知道它的安全性如何,但是由于我并没有那么重要,我想我会尝试的。如果能够成功完成,我将添加自己的答案。
-
为什么它必须在您的服务器上而不是在客户端上执行?
-
我认为这是一个错误,但是您可以尝试使用节点虚拟机的东西--nodejs.org/api/vm.html
-
这是一个有趣的编程游戏概念,我不能相信客户端能够执行代码。出于这个原因,我想在服务器端执行此操作,因为输出将被序列化并发送到1个或多个其他客户端。看起来像vm模块或包装它的东西是我想要的。
-
@CoryGross您是否发现沙堡或沙箱存在任何漏洞?我正在建立类似的东西(允许用户提交js代码),您的输入将对我有很大帮助:)
-
还有一个类似的问题(但年龄较大),这里有一个有趣的可接受答案(提到一些重要问题):stackoverflow.com/questions/7446729/
-
我对您如何解决它感兴趣。我有一个类似的问题:stackoverflow.com/questions/32773981/我使用虚拟机"解决了"它,我仍在测试是否有任何方法可以利用我的解决方案。
您可以将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"所指出的那样,它似乎存在缺陷。请查看评论。
-
这似乎并不安全,例如:vm.runInNewContext(this.constructor.constructor("return process")().exit());(来自vm2自述文件:github.com/patriksimek/vm2)。
-
有没有针对无限循环的保护措施?
-
@Qwertiy,您可以像这样在vm.runInNewContext(内使用超时,而(true)1 , {}, {timeout: 1000});。
一种替代方法是使用http://github.com/patriksimek/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浏览器的所有操作,并且还提供了将一组函数导出到沙箱的机会。
-
这时,监狱入狱了:github.com/asvd/jailed/issues/33
-
@ arve0你是正确的,在节点下被判入狱,正在准备修复程序
-
替代方法:github.com/patriksimek/vm2看起来很安全,但要注意日志潜在的爆发,我会小心一点。
由于gf3无法提供防止沙箱损坏的保护,因此此答案已过时
http://gf3.github.io/sandbox/-它使用require('child_process')而不是require('vm')。
-
我将继续接受,在接下来的几天中,我将同时查看上面链接到的沙箱和沙堡模块。谢谢。
-
不要误导,gf3 / sandbox同时使用子进程和vm模块,请检查代码。并且所有沙盒解决方案都一样。
-
对于未来的观看者来说,目前gf3可以被利用并且可以被打破。
-
警告! gf3 / sandbox尚未在1年内更新,仍然存在一个尚可解决的沙盒问题:github.com/gf3/sandbox/issues/29
根据您的使用情况,建议您也考虑使用gVisor等虚拟环境保护沙箱。您可以在这里找到一些信息。