Javascript 如何在服务器端运行不受信任的代码?
我试图在linux+node.js中使用沙盒模块运行不受信任的javascript代码,但它已经坏了,我所需要的只是让用户编写javascript程序来打印一些文本。不允许其他i/o,只使用纯javascript,不允许使用其他节点模块。 如果真的不可能做到,那么对于这类任务,您建议使用什么其他语言?我需要的最小功能集是一些数学、正则表达式、字符串操作和基本JSON函数。Javascript 如何在服务器端运行不受信任的代码?,javascript,linux,node.js,Javascript,Linux,Node.js,我试图在linux+node.js中使用沙盒模块运行不受信任的javascript代码,但它已经坏了,我所需要的只是让用户编写javascript程序来打印一些文本。不允许其他i/o,只使用纯javascript,不允许使用其他节点模块。 如果真的不可能做到,那么对于这类任务,您建议使用什么其他语言?我需要的最小功能集是一些数学、正则表达式、字符串操作和基本JSON函数。 脚本最多会运行5秒,然后进程就会终止,我如何才能实现这一点?沙盒的基本思想是,您需要预定义为全局变量的变量来执行操作,因此如
脚本最多会运行5秒,然后进程就会终止,我如何才能实现这一点?沙盒的基本思想是,您需要预定义为全局变量的变量来执行操作,因此如果您通过取消设置或用受控变量替换脚本来拒绝它们,它将无法逃脱。只要你什么都不忘 首先替换deny require()或将其替换为受控对象。
不要忘记过程和“全局”也称为“根”,困难的是不要忘记任何东西,这就是为什么依赖别人建立沙箱是好的;-) 问问自己以下问题:
eval()
和require()
的原因,您无法使用node.js中的JavaScript解释器(这两种解释器都允许破解程序逃离沙箱)
解释器必须确保所解释的代码不能访问除您提供的几个全局符号之外的任何内容。例如,这意味着不能有eval()
函数(或者必须确保此函数仅在您自己的JavaScript解释器的上下文中计算)
这种方法的缺点是:需要大量的工作,如果您在解释器中出错,破解程序可能会离开沙箱
另一种方法是清理代码并使用node.js的eval()
运行它。您可以通过在现有代码上运行一组regexp来清除现有代码,如/eval\s*[(]//g
,以删除恶意代码部分
这种方法的缺点:很容易犯错误,使您容易受到攻击。例如,regexp和node.js认为的“空白”之间可能不匹配。一些模糊的unicode空白可能被解释器接受,但regexp不接受,这将允许攻击者运行eval()
我的建议是:编写一个小的演示测试用例,展示沙盒模块是如何损坏的,并将其修复。这将节省您大量的时间和精力,如果沙盒中有bug,这不会是您的错(至少不是完全的错).如果您能够承受性能损失,您可以在一个一次性虚拟机中运行JS,并具有适当的CPU和内存限制 当然,那么您就信任VM解决方案的安全性了。通过将它与普通的JS沙盒一起使用,您将拥有两层安全性 对于附加层,将沙盒放在与主应用程序不同的物理机器上。是一个非常棒的新手,它使用s和创建沙盒 下面是一个(类似于)使用and的实现
这只是为了证明一个人可以安全地运行用多种编程语言编写的不受信任的代码,包括
node.js
我现在面临着一个类似的问题,我只看到了沙盒模块的一些不好的地方
如果您不需要特定于节点环境的任何东西,我想最好的方法是使用无头浏览器,如PhantomJS或Chimera,将其用作沙箱环境。我最近创建了一个库,用于沙箱不受信任的代码,它似乎符合要求(对于Node.js,在受限进程中执行代码,对于web浏览器,在沙盒iframe内的辅助进程中执行代码):
有机会将给定的方法集从主应用程序导出到沙箱中,从而提供任何自定义API和特权集(这一特性实际上就是我决定从头开始创建库的原因)所提到的数学、regexp和字符串相关的东西是由JavaScript本身提供的,任何额外的东西都可以从外部显式导出(比如一些与主应用程序通信的函数).知道现在回答这个问题已经很晚了,我猜下面的工具可能是一个增值工具,上面的回答/评论中没有提到 尝试实现类似的用例。在浏览了web资源之后,似乎对沙盒环境(nodejs)的处理非常好
它基本上满足了沙盒功能,如限制对内置或外部模块的访问、沙盒之间的数据交换等。答案很晚,但可能是一个有趣的想法 静态代码分析=>AST操作=>代码生成
function () {
a = 1;
window.b = 1;
eval('window.c()');
}
function () {
var a, window = {}, eval = function () {}; // variable overwriting
a = 1;
window.b = 1;
eval('window.c()');
}