31

我正在尝试使用沙盒模块在 linux + node.js 中运行不受信任的 javascript 代码,但它已损坏,我所需要的只是让用户编写打印输出一些文本的 javascript 程序。不允许其他 i/o,只使用普通的 javascript,没有其​​他节点模块。如果它真的不可能做到,你建议用什么其他语言来完成这种任务?我需要的最小功能集是一些数学、正则表达式、字符串操作和基本的 JSON 函数。脚本将运行 5 秒,然后进程将被终止,我该如何实现?

4

9 回答 9

13

我在这些问题(vm2, jailed)中看到的所有库都试图隔离node进程本身。这类“监狱”不断被打破,并且高度依赖于未来对node标准库的升级,以免暴露另一个攻击媒介。

另一种方法是V8::Isolate直接使用该类。它旨在隔离 Google Chrome & 中的 JavaScript node,因此您可以期望它得到完全维护,并且比您、我或单个库维护者能够做到的更安全。这个类只能运行“纯” JavaScript。它具有完整的 ECMAScript 实现,但没有浏览器 API 或nodeAPI。
这就是Cloudflare他们的Worker产品所使用的。

deno,由 的创建者开发的新语言node,默认情况下使用完全相同的东西进行沙箱化,并根据您启用的标志公开标准库的部分内容。

在一个node环境中,你可以使用isolated-vm. v8::Isolate这是一个了不起的库,可以使用您要单独运行的代码创建d 个子进程。

它提供了将值和函数传递给隔离和返回的方法。这并不像大多数“监狱”库那样简单易用,但可以保证 JavaScript 代码的实际沙盒。
由于它是“纯”JavaScript,因此唯一的转义是您以注入函数的形式提供的转义。
此外,它会随着每个node版本自动更新,因为它使用node自己的v8::Isolate.
主要的痛点之一是,如果您想在脚本中注入库,您可能需要使用包捆绑webpack器,以便将所有内容捆绑到库可以使用的单个脚本中。

我个人使用它在爬虫中运行用户提供的代码,以使用用户提供的代码从网页中提取信息,它可以创造奇迹。

于 2020-03-27T10:26:44.857 回答
9

我最近创建了一个库,用于对不受信任的代码进行沙盒处理,它似乎符合要求(在 Node.js 的情况下在受限进程中执行代码,并在 Web 浏览器的沙盒 iframe 内的 Worker 中执行代码):

https://github.com/asvd/jailed

有机会将给定的一组方法从主应用程序导出到沙箱中,从而提供任何自定义 API 和一组权限(该功能实际上是我决定从头开始制作库的原因)。上面提到的数学、正则表达式和字符串相关的东西是由 JavaScript 本身提供的,任何额外的东西都可以从外部显式导出(比如一些用于与主应用程序通信的函数)。

于 2014-09-18T14:37:03.407 回答
3

沙盒的基本思想是,您需要将变量预定义为全局变量来执行操作,因此如果您通过取消设置它们或将它们替换为受控变量来拒绝脚本它们,它就无法逃脱。只要你什么都不忘。

首先替换拒绝 require() 或用受控的东西替换它。不要忘记进程和“全局”又名“根”,难的是不要忘记任何事情,这就是为什么依靠别人建立沙箱是件好事;-)

于 2012-06-09T11:50:16.957 回答
3

Docker.io是一个很棒的新手,它使用LXCCGroups来创建沙箱。

这是一个使用DockerGo Lang实现的在线要点(类似于codepad.org )

这只是为了证明可以在Docker 容器中安全地运行用多种编程语言编写的不受信任的代码,包括node.js

于 2013-12-05T06:24:01.880 回答
3

Know its pretty late to answer the question, guess the below tool might be a value add which is not mentioned in the above answers/comments.

Trying to implement similar use-case. After have gone through the web resources, https://www.npmjs.com/package/vm2 seems to be handling the sandbox environment(nodejs) pretty well.

It's pretty much satisfies the sandboxing features like restricting the access to builtin or external modules, data exchanges between sandbox, etc.

于 2017-08-11T10:06:59.520 回答
1

如果您能承受性能损失,您可以在具有适当 CPU 和内存限制的一次性虚拟机中运行 JS。

当然,那么您就是信任 VM 解决方案的安全性。通过将它与普通的 JS 沙箱一起使用,您将拥有两层安全性。

对于附加层,将沙箱放在与主应用程序不同的物理机器上。

于 2013-08-02T10:10:39.713 回答
0

我现在面临着类似的问题,我只阅读有关沙盒模块的坏消息。

如果您不需要特定于节点环境的任何内容,我认为最好的方法是使用无头浏览器(例如 PhantomJS 或 Chimera)用作沙箱环境。

于 2014-02-03T09:45:23.483 回答
0

一个迟到的答案,但也许是一个有趣的想法。

静态代码分析=> AST 操作=>代码生成

  1. 静态分析将解析源代码的AST。AST 提供了一个通用的数据结构,让我们可以遍历和修改源代码。
  2. 通过 AST 操作,我们可以找出对外部范围内任何敏感变量的所有标识符引用。如果需要,我们可以在函数体的开头重新声明和初始化它们,从而覆盖它们。因此,从内部到外部的引用都在控制之中。
  3. 从 AST 生成代码也很容易。

例如,一个函数如下所示:

function () {
    a = 1;
    window.b = 1;
    eval('window.c()');
}

基于 JS 代码解析器的静态分析使我们能够在原始函数体之前插入变量声明语句:

function () {
    var a, window = {}, eval = function () {}; // variable overwriting
    a = 1;
    window.b = 1;
    eval('window.c()');
}

而已。

应该考虑更多的覆盖,例如eval()new Function()其他全局对象或 API。解析过程中的警告应该组织好并报告。

一些相关的工作按顺序进行:

  • esprima,用于多用途分析的 ECMAScript 解析基础架构。
  • estraverse,ECMAScript JS AST 遍历函数。
  • escope,ECMAScript 范围分析器。
  • escodegen,ECMAScript 代码生成器。

我基于上述的做法是function-sandbox

于 2018-02-24T10:16:27.670 回答
-3

问自己这些问题:

  1. 你是这个星球上最聪明的人之一吗?
  2. 你是否经常拒绝谷歌、Mozilla 和卡巴斯基实验室的工作机会,因为这会让你感到厌烦?
  3. “不受信任的代码”是来自与您在同一家公司工作的人,还是来自全球各地的犯罪分子和无聊的电脑孩子?
  4. 您确定 node.js 没有可能通过您的沙箱泄漏的安全漏洞吗?
  5. 你能写出完美的 100% 无错误代码吗?
  6. 你了解 JavaScript 的一切吗?

正如您通过沙盒模块的实验已经知道的那样,编写自己的沙盒并非易事。沙盒的主要问题是你必须把一切都做好。一个错误将彻底破坏您的安全性,这就是为什么浏览器开发人员与全球各地的破解者不断战斗的原因。

也就是说,简单的沙箱很容易做到。首先,你需要编写自己的 JavaScript 解释器,因为你不能使用 node.js 中的解释器,因为eval()and require()(两者都会让破解者逃离你的沙箱)。

解释器必须确保解释的代码不能访问除了您提供的少数全局符号之外的任何东西。例如,这意味着不能有eval()函数(或者您必须确保仅在您自己的 JavaScript 解释器的上下文中评估此函数)。

这种方法的缺点:工作量很大,如果你在解释器中犯了错误,破解者可以离开沙箱。

另一种方法是清理代码并使用 node.js 运行它eval()。您可以通过运行一堆正则表达式来清理现有代码,就像/eval\s*[(]//g删除恶意代码部分一样。

这种方法的缺点:很容易犯错误,使您容易受到攻击。例如,regexp 和 node.js 认为的“空白”之间可能存在不匹配。解释器可能会接受一些晦涩的 unicode 空格,但不会被允许攻击者运行的正则表达式接受eval()

我的建议:编写一个小型演示测试用例,展示沙盒模块是如何被破坏并修复的。它将为您节省大量时间和精力,并且如果沙箱中有错误,那不是您的错(嗯,至少不完全是)。

于 2012-06-09T12:49:18.907 回答