如何在服务器端运行不受信任的代码?

2024-10-21 09:14:00
admin
原创
72
摘要:问题描述:我正在尝试使用 sandbox 模块在 linux + node.js 中运行不受信任的 javascript 代码,但它有问题,我需要的只是让用户编写打印一些文本的 javascript 程序。不允许其他 i/o,只能使用纯 javascript,不能使用其他节点模块。如果真的不可能做到,您建议使...

问题描述:

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


解决方案 1:

我见过的所有在这些问题中提到的库(vm2jailed)都在尝试隔离node进程本身。这些“监狱”经常被破坏,并且高度依赖于未来对node标准库的升级,以免暴露另一个攻击媒介。

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

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

node环境中,您可以使用isolated-vm。这是一个很棒的库,它v8::Isolate使用您想要单独运行的代码创建 d 个子进程。

它提供了将值和函数传递到隔离并返回的方法。这不像大多数“监禁”库那样简单易用,但可以保证您对 JavaScript 代码进行真正的沙盒处理。

由于它是“纯”JavaScript,因此唯一的逃逸是您以注入函数的形式提供的逃逸。此外,由于它使用自己的,因此

它会随着每个版本自动更新。
主要的麻烦之一是,如果您想在脚本中注入库,您可能需要使用像这样的包捆绑器,以便将所有内容捆绑到库可以使用的单个脚本中。node`node`v8::Isolate
webpack

我个人使用它在爬虫中运行用户提供的代码,使用用户提供的代码从网页中提取信息,效果非常好。

解决方案 2:

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

https://github.com/asvd/jailed

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

解决方案 3:

Docker.io是一个很棒的新兴事物,它使用LXC和CGroups来创建沙箱。

以下是使用Docker和Go Lang实现的在线 gist(类似于codepad.org)

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

解决方案 4:

沙箱的基本思想是,你需要将变量预定义为全局变量才能执行操作,因此如果你通过取消设置或用受控变量替换来拒绝脚本执行这些变量,则脚本无法逃脱。只要你没有忘记任何东西。

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

解决方案 5:

知道回答这个问题已经很晚了,猜测下面的工具可能会增加上面的答案/评论中没有提到的价值。

尝试实现类似的用例。浏览完网络资源后,https://www.npmjs.com/package/vm2似乎可以很好地处理沙盒环境 (nodejs)。

它几乎满足了沙盒功能,例如限制对内置或外部模块的访问、沙盒之间的数据交换等。

解决方案 6:

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

当然,那你就信任 VM 解决方案的安全性了。通过与普通的 JS 沙箱一起使用,你将获得两层安全性。

为了增加一层,请将沙箱放在与主应用程序不同的物理机器上。

解决方案 7:

我现在正面临类似的问题,而且我只读到有关沙盒模块的坏消息。

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

解决方案 8:

虽然回答得有点晚,但也许是一个有趣的想法。

静态代码分析=> 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。

解决方案 9:

我们在开发我们的一款产品时也遇到了同样的问题。我们希望允许用户提供他们自己的自定义(不受信任的)代码,我们会在产品的特定关键事件(例如任务完成)时运行这些代码。这几乎是 webhook 的更好替代方案!

我们最终决定使用 AWS Lambda、Rust 和 V8::Isolate其他一些组件构建一个单独的服务,使其不仅安全,而且速度非常快。我们还添加了自己的集成,因为 V8 不支持 Web 或特定于 Node 的 API。这还使我们能够做一些巧妙的事情,例如限制脚本可以与之通信的端点,甚至通过为特定请求/域fetch()注入预配置的标头来预先验证请求。Authorization

我们没有将我们的工作开源,而是选择以托管产品的形式向其他人提供服务。该服务是全球部署的,不需要设置,默认情况下完全无状态!您可以在https://scriptable.run上查看。

解决方案 10:

问自己这些问题:

  1. 您是地球上最聪明的人之一吗?

  2. 您是否会因为觉得无聊而经常拒绝 Google、Mozilla 和卡巴斯基实验室的工作邀请?

  3. “不受信任的代码”是来自与您在同一家公司工作的人,还是来自世界各地的犯罪分子和无聊的计算机小子?

  4. 您确定 node.js 没有可能通过您的沙箱泄漏的安全漏洞吗?

  5. 你能编写出完美、100%无错误的代码吗?

  6. 你对 JavaScript 了如指掌吗?

正如您通过对沙盒模块的试验所知道的那样,编写自己的沙盒并非易事。沙盒的主要问题是您必须确保一切都正确无误。一个错误就会完全破坏您的安全性,这就是浏览器开发人员与全球各地的破解者不断斗争的原因。

话虽如此,简单的沙箱还是很容易实现的。首先,您需要编写自己的 JavaScript 解释器,因为您不能使用 node.js 中的解释器,因为eval()require()(两者都允许破解者逃离您的沙箱)。

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

这种方法的缺点:需要做大量工作,而且如果您的解释器出现错误,破解者就可以离开沙箱。

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

这种方法的缺点:很容易犯错误,导致您容易受到攻击。例如,正则表达式和 node.js 所认为的“空格”可能不匹配。一些模糊的 unicode 空格可能被解释器接受,但正则表达式却不接受,这将允许攻击者运行eval()

我的建议是:编写一个小型演示测试案例,展示沙盒模块是如何损坏的,然后修复它。这将节省您大量的时间和精力,而且如果沙盒中存在错误,那不是您的错(至少不是完全是您的错)。

相关推荐
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   601  
  华为IPD与传统研发模式的8大差异在快速变化的商业环境中,产品研发模式的选择直接决定了企业的市场响应速度和竞争力。华为作为全球领先的通信技术解决方案供应商,其成功在很大程度上得益于对产品研发模式的持续创新。华为引入并深度定制的集成产品开发(IPD)体系,相较于传统的研发模式,展现出了显著的差异和优势。本文将详细探讨华为...
IPD流程是谁发明的   7  
  如何通过IPD流程缩短产品上市时间?在快速变化的市场环境中,产品上市时间成为企业竞争力的关键因素之一。集成产品开发(IPD, Integrated Product Development)作为一种先进的产品研发管理方法,通过其结构化的流程设计和跨部门协作机制,显著缩短了产品上市时间,提高了市场响应速度。本文将深入探讨如...
华为IPD流程   9  
  在项目管理领域,IPD(Integrated Product Development,集成产品开发)流程图是连接创意、设计与市场成功的桥梁。它不仅是一个视觉工具,更是一种战略思维方式的体现,帮助团队高效协同,确保产品按时、按质、按量推向市场。尽管IPD流程图可能初看之下显得错综复杂,但只需掌握几个关键点,你便能轻松驾驭...
IPD开发流程管理   8  
  在项目管理领域,集成产品开发(IPD)流程被视为提升产品上市速度、增强团队协作与创新能力的重要工具。然而,尽管IPD流程拥有诸多优势,其实施过程中仍可能遭遇多种挑战,导致项目失败。本文旨在深入探讨八个常见的IPD流程失败原因,并提出相应的解决方法,以帮助项目管理者规避风险,确保项目成功。缺乏明确的项目目标与战略对齐IP...
IPD流程图   8  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用