安全沙箱并执行用户提交的 JavaScript?
Posted
技术标签:
【中文标题】安全沙箱并执行用户提交的 JavaScript?【英文标题】:Safely sandbox and execute user submitted JavaScript? 【发布时间】:2013-07-04 23:49:49 【问题描述】:我希望能够让用户提交任意 javascript 代码,然后将其发送到 Node.JS 服务器并在输出被发送回多个客户端(作为 JSON)之前安全地执行。我想到了eval
函数,但我知道这有多个安全问题(用户提交的代码将能够访问 Node 的文件 API 等)。我见过一些项目,如 Microsoft Web Sandbox 和 Google Caja,它们允许执行经过清理的标记和脚本(用于在网站上嵌入第三方广告),但似乎这些是客户端工具,我不确定它们是否可以在 Node 中安全使用。
是否有一种标准方法可以在 Node 中沙箱并执行不受信任的 JavaScript 以获取输出。尝试在服务器端执行此操作是错误的吗?
编辑: 用户能够利用 JavaScript 的全部功能并不重要,事实上,最好能够选择哪些 API 将提供给用户代码.
编辑:我将继续更新我发现的内容。这个 Sandcastle 模块 (bcoe/sandcastle
) 似乎旨在实现我的想法。不知道它有多安全,但因为我这不是什么太重要的事情,我想我会尝试一下。如果我能够成功地做到这一点,我会添加我自己的答案。
【问题讨论】:
我认为这是一个错误,但你可以试试 node 'vm' 的东西--nodejs.org/api/vm.html 这是一个有趣的编程游戏概念,我不能相信客户端执行代码。出于这个原因,我想在服务器端进行,因为输出将被序列化并发送到 1 个或多个其他客户端。它看起来像 vm 模块或包装它的东西是我想要的。 @CoryGross 您是否发现了沙堡或沙箱的任何漏洞?我正在构建类似的东西(允许用户提交 js 代码),你的输入会对我有很大帮助:) 这里有一个类似的问题(但较旧)有一个有趣的公认答案(提到一些重要问题):***.com/questions/7446729/… 我对你是如何解决的很感兴趣。我有一个类似的问题:***.com/questions/32773981/… 我使用虚拟机“解决”了它,我仍在测试是否有任何方法可以利用我的解决方案。 【参考方案1】:您可以通过 vm.runInContext('js code', context) 在 nodejs 中使用沙盒支持,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
警告:正如“s4y”所指出的,它似乎有缺陷。请看cmets。
【讨论】:
这似乎不安全,例如:vm.runInNewContext('this.constructor.constructor("return process")().exit()');
(来自 vm2 README:github.com/patriksimek/vm2)。
是否有针对无限循环的保护措施?
@Qwertiy 你可以像这样vm.runInNewContext(
while (true) 1, , timeout: 1000);
使用毫秒级超时。【参考方案2】:
另一种选择是使用http://github.com/patriksimek/vm2:
$ npm install vm2
然后:
const VM = require('vm2');
const vm = new VM();
vm.run(`1 + 1`); // => 2
如其他答案的 cmets 中所述。
我不知道它有多安全,但它至少声称它可以安全地运行不受信任的代码(在其自述文件中)。就此处其他答案中建议的解决方案而言,我找不到任何明显的安全问题。
【讨论】:
【参考方案3】:此答案已过时,因为 gf3 不提供针对沙盒破坏的保护
http://gf3.github.io/sandbox/ - 它使用require('child_process')
而不是require('vm')
。
【讨论】:
我将继续接受,我将在接下来的几天里同时查看沙盒和上面链接到的沙堡模块。谢谢。 不要误导,gf3/sandbox同时使用子进程和vm模块,检查代码。所有沙盒解决方案都这样做。 对于未来的观众,目前 gf3 是可利用的并且可以被破解。 小心! gf3/sandbox 1 年没有更新了,还有一个可以破解沙盒的问题:github.com/gf3/sandbox/issues/29【参考方案4】:在Node.js下你可以创建一个沙盒子进程,但你也需要在代码后面加上"use strict";
,否则有可能用arguments.callee.caller
打破沙盒。
不确定为什么需要将其发送到服务器,因为代码也可能在沙盒网络工作者中执行。
还可以看看我的 Jailed 库,它简化了刚才提到的 Node.js 和网络浏览器的所有内容,还提供了将一组函数导出到沙箱的机会。
【讨论】:
此时Jailed被破:github.com/asvd/jailed/issues/33 @arve0 你是对的,jailed 在 node 下被攻陷,正在准备修复 Alternative: github.com/patriksimek/vm2 似乎是安全的,但看到日志潜在的突破,我会小心的。【参考方案5】:根据您的使用情况,我建议您还考虑使用 gVisor 等虚拟环境保护您的沙盒。你可以找到一些信息here。
【讨论】:
以上是关于安全沙箱并执行用户提交的 JavaScript?的主要内容,如果未能解决你的问题,请参考以下文章