我想在我的服务器上模拟(不安全的)客户端代码,我正在寻找一种合适的语言来实现。我更愿意让客户使用我将用于模拟的相同语言编写。
- 安全是首要问题
- 最好是一种众所周知的语言(便于客户学习语法)
- 应该很容易禁用/启用沙箱中可用的语言功能
- 如果我能一步步模拟代码就更好了
理想情况下,我会简单地构建一些接口(interface)(并发布这些接口(interface)),加载客户端代码,并通过允许它仅使用我的接口(interface) + 我精心选择的标准 API 的子集来模拟该代码。
在此模拟过程中,我应该能够限制客户端代码使用的资源(时间和内存)。如果我可以一步一步地模拟代码,那将是额外的好处,那样我总是可以返回一个确定性的解决方案。
性能并不是真正的问题。这个想法是让客户为小型游戏/拼图编写自定义 AI。游戏将被模拟(在服务器上!)并将结果返回给用户。
最初我想自己构建一个外部 DSL,包括解析器和求值器,但也许有现成的解决方案?
最佳答案
我的选择是使用一些无需自动提供对某些扩展框架(如 .Net 或 Java)的访问即可使用的脚本语言 - 添加功能比限制它们更容易。游戏引擎脚本语言,如 LUA可能是一个选项,通常带有多个平台的实现以在其中使用它们。
一般注意事项:
无论您选择哪种语言/框架,请确保您可以从以下风险中恢复/接受以下风险:
- 致命异常(如递归函数导致的堆栈溢出)
- 无限内存分配/内存不足异常
- 长时间运行的任务
谨防公开允许用户在您的控制之外创建新线程/任务/同步对象(锁/信号量)的 API,或在提供此类 API 的平台上构建。允许此类方法可能会打开您的服务器资源以无限消耗或 DOS/死锁...
请注意,长时间运行的任务对于任何合理的语言都是一个问题,因为您无法通过查看程序来确定程序是否会结束 - halting problem .无论您选择什么平台,您都必须想出一个解决方案。
.Net/C#:
可以查看Terrarium这在 .Net 中正是这样做的——在沙盒环境中的用户机器上运行不受信任的代码。
.Net 提供了一种限制使用多个 API 的方法 - How to: Run Partially Trusted Code in a Sandbox是一个很好的起点。请注意,正如@Andrew 指出的那样,最好验证用户提供的程序集(直接或从用户的源代码编译)是否使用您不喜欢的 API(或者相反 - 仅使用 API)你允许的)除了基本的沙盒。在单独的 AppDomain 中运行的部分受信任的代码可以很好地保护您免受不太敌对的代码。
Stack overflows通常很难预防,需要自定义主机才能在 .Net 中处理。可以使用 Thread.Abort 或使用用户代码关闭 AppDomain 来终止长时间运行的任务。
关于c# - 适合在沙箱中运行客户端代码的语言,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14431652/