安全运行用户代码
Posted
技术标签:
【中文标题】安全运行用户代码【英文标题】:Securely running user's code 【发布时间】:2015-07-14 14:57:52 【问题描述】:我希望创建一个 AI 环境,用户可以在其中提交自己的 AI 代码并让他们参与竞争。语言可以是任何语言,但首选 javascript 或 Python 等易于学习的语言。
基本上,我看到三个选项有几个变体:
制作我自己的语言,例如一个 JavaScript 克隆,只有非常基本的功能,如变量、循环、条件、数组等。如果我想正确实现通用语言功能,这是一项大量工作。
1.1 采用现有语言并将其剥离到其核心。只需从 Python 中删除许多特性,直到只剩下上述特性(变量、条件等)。仍然有很多工作要做,尤其是如果我想跟上上游(尽管我也可以忽略上游)。
使用语言的内置功能将其锁定。我从 php 知道您可以禁用函数并四处搜索,Python 似乎存在类似的解决方案(有很多警告)。为此,我需要对所有语言的特性有一个很好的理解,并且不会遗漏任何东西。
2.1。制作一个预处理器,拒绝包含危险内容的代码(最好基于白名单)。与选项 1 类似,除了我只需要实现解析器而不实现所有功能:预处理器必须理解该语言,以便您可以拥有名为“eval”的变量但不调用名为“评估”。仍有大量工作,但比选项 1 更易于管理。
2.2。在非常封闭的环境中运行代码。 Chroot,没有不必要的权限......也许在虚拟机或容器中。某种意义上的东西。我必须研究如何实现这一目标以及如何让它以安全的方式给我结果,但这似乎是可行的。
手动通读所有代码。可以在小范围内或与版主一起使用,但仍然乏味且容易出错(我可能会错过 if (user.id = 0)
之类的内容)。
我想象 2.2 的工作方式是这样的:在虚拟机(或其他东西)中运行两个 AI,并将其限制为仅与主机通信(没有其他 Internet 或 LAN 访问)。两个 AI 在单独的机器上运行,并通过在主机上运行的 API 相互通信(嗯,通过比赛场地,因此它们可以看到彼此的位置)。
选项 2.2 似乎是最可行的,但也相对 hacky...我让某人的代码在虚拟化或锁定的环境中松散,希望这样可以让他们继续使用,同时为他们提供免费的 DoS 游戏或突破环境。再说一次,大多数其他选择也好不了多少。
TL;DR: 本质上我的问题是:我如何让人们给我一个 AI 的“逻辑”(我认为使用代码最容易完成)然后运行在不影响系统功能的情况下? 必须至少有 2 个 AI 在同一个比赛场地上工作。
【问题讨论】:
在语言层面做这件事太容易出错了。几乎任何语言的特性都可能被滥用。即使是像正则表达式这样看似无害的东西,使用catastrophic backtracking 也会使系统缺乏 CPU 资源。一个容器可以解决很多这样的问题。使用 Docker 之类的东西,您可以指定 CPU 配额,这样就没有一个容器可以让 CPU 饿死。您还可以以具有有限磁盘访问权限的用户身份运行容器。 @vcsjones 好建议,请作为答案发布。澄清一下,您的意思是任何基于语言的选项,包括编写我自己的语言? 【参考方案1】:这实际上只是一个插件系统,因此研究其他人如何实现插件是一个很好的起点。特别是,我会研究 Chrome 和 Safari 等网络浏览器及其插件系统。
现代插件系统的一个共同主题是进程隔离。理想情况下,您应该在沙箱中的自己的进程空间中运行插件。在 OS X 中查看 XPC,它是专门为这个问题设计的。在 Linux(或更便携)上,我可能会看一下 NaCl(本机客户端)。 JVM 还旨在提供沙盒,并提供丰富的语言选择。 (也就是说,我个人并不认为 JVM 是一个非常强大的沙箱。它有安全问题的历史。)
总的来说,我对这类项目的偏好是与语言无关的 API。我最常使用 REST API(或“类 REST”)。这允许插件受到高度限制,同时不限制语言选择。我喜欢尽可能简单的 HTTP 进行通信,因为它对多种语言有丰富的支持,因此对插件的限制很小。事实上,根据您的描述,您甚至不必在硬件上运行插件(当然也不必在主服务器上)。使插件远程客户端消除了许多潜在的问题。
但最终,我认为像你的“2.2”这样的东西是正确的方向。
【讨论】:
我想到了一个 API。我(事后看来,错误地)立即拒绝人们将机器人连接到公共 API 的想法的原因是延迟。解决一个头痛;开始另一个(我以前参加过实时多人游戏,很难做到正确)。但也许通过在虚拟化环境中运行代码并让它连接到同一物理主机(或 LAN)上的 API,我可以规避延迟问题。唔。肯定赞成,也许稍后会接受答案。谢谢!以上是关于安全运行用户代码的主要内容,如果未能解决你的问题,请参考以下文章
如何允许最终用户在特定安全约束下在 JEE 环境中运行脚本?