适用于在沙盒中运行客户端代码的语言

2022-09-04 04:08:53

我想在我的服务器上模拟(不安全的)客户端代码,我正在寻找一种合适的语言来做到这一点。我更喜欢让客户端用与我用于模拟的语言相同的语言编写。

  • 安全是首要关注点
  • 最好是众所周知的语言(易于客户学习语法)
  • 应该易于禁用/启用沙盒中可用的语言功能
  • 如果我真的可以一步一步地模拟代码,那将是一个加分项

理想情况下,我只需构建几个接口(并发布这些接口),加载客户端代码,并通过允许它仅使用我的接口+我精心选择的标准API的子集来模拟该代码。

在此模拟期间,我应该能够限制客户端代码使用的资源(时间和内存)。好处是,如果我可以一步一步地模拟代码,这样我总是可以返回一个确定性的解决方案。

性能并不是真正的问题。这个想法是允许客户为小游戏/拼图编写自定义AI。游戏将被模拟(在服务器上!),并将结果返回给用户。

最初,我正在考虑自己构建外部DSL,包括解析器和评估器,但也许有一个现成的解决方案?


答案 1

我的选择是使用一些脚本语言,这些语言可以在不自动提供对某些广泛框架(如.Net或Java)的访问的情况下使用 - 添加功能比限制它们更容易。像LUA这样的游戏引擎脚本语言可能是一种选择,并且通常带有多个平台的实现来使用它们。

一般注意事项:

无论您选择哪种语言/框架,请确保您能够从以下风险中恢复/接受以下风险:

  • 致命异常(如递归函数导致的堆栈溢出)
  • 无限内存分配/内存不足异常
  • 长时间运行的任务

请注意公开允许用户在您的控制范围之外创建新线程/任务/同步对象(锁/信号量)的 API,或在提供此类 API 的平台上进行构建。允许这些方法可能会使服务器的资源无限制地消耗或DOS/死锁...

请注意,长时间运行的任务是任何合理语言的问题,因为您无法通过查看程序来确定程序是否结束 - 停止问题。无论您选择哪种平台,都必须找出解决方案。

.Net/C#:

您可以查看Terrarium,它在.Net中完全做到了这一点 - 在沙盒环境中的用户计算机上运行不受信任的代码。

.Net 提供了一种限制使用多个 API 的方法 - 如何:在沙盒中运行部分受信任的代码是一个很好的起点。请注意,正如@Andrew所指出的那样,除了基本的沙盒之外,最好验证用户提供的程序集(直接或从用户的源代码编译)是否不使用您不喜欢的 API(甚至相反 - 仅使用您允许的 API)。在单独的 AppDomain 中运行的部分受信任的代码可为您提供针对不太敌对的代码的良好保护。

堆栈溢出通常很难防止,并且需要在 .Net 中处理自定义主机。可以使用 Thread.Abort 终止长时间运行的任务,也可以使用用户的代码关闭 AppDomain。


答案 2

我会推荐.NET(C#,VB和F#)。你可以利用 JIT 让服务器以编程方式编译代码,使用反射来分析代码,并让每个客户端在单独的 AppDomain 中运行,以实现安全性和代码隔离。