Ruby sandboxing与整合脚本语言
我目前正在Ruby中使用基于文本的游戏引擎,应用程序分为/ lib中的Ruby代码和/ data中的YAML数据,在游戏需要时加载该数据。 我想允许数据文件包含基本脚本,主要是在事件/观察者模型中。 不过,我也希望用户能够生成和共享自定义场景,而不必担心嵌入脚本中的恶意代码。
附录:我最初的计划是将用户创建的内容分成两种类型,即仅用于数据(因此安全)的“模块”和添加了附加功能(但显然不安全)的插件。 为了类比桌面游戏,模块将像发布的冒险场景和内容一样,插件将是包含附加规则和系统的规则手册。
示例脚本(课程的语法可根据解决方案进行更改):
---
Location:
observers:
on_door_open: |
monster = spawn_monster(:goblin);
monster.add_item(random_item());
monster.hostile = true;
从安全角度来看,如果脚本严格选择加入,这可能是理想的选择,可能是通过包含一些DSL的mixin,例如:
class Frog
include Scriptable
def jump; ... ; end # this can be called from a script
allow_scripting :jump
def ribbit; ... ; end # this cannot be called from a script
end
我看了三个四个选项,但我不确定哪个是最好的方法:
使用Ruby脚本,但在某种沙箱中。
优点:非常熟悉Ruby,不需要“粘合”代码或在语言之间集成对象的问题。
缺点:对安全问题或沙盒不太了解,没有找到任何似乎适合的现成解决方案。
实现嵌入另一种脚本语言,例如Lua。
优点: Ruby和Lua是基于C的,因此绑定应该相当简单。 Lua是一种非常流行的语言,如果我稍后遇到问题,可以提供帮助。 安全,因为我没有特别绑定的任何功能将不可用于脚本。
缺点:现有的Ruby-Lua绑定似乎是单向的,旧的和维护不当的,或者两者兼而有之。 将脚本语言嵌入到另一种脚本语言中看起来很狡猾。
使用Ruby解释器实现自定义脚本语言。 我一直在试验Treetop,并且制作一个足以处理脚本的简单语法应该不会太难。
优点:无需嵌入其他语言。 只有我特别实现的功能才能用于脚本。
缺点:矫枉过正。 “不在此建”综合征。 可能发生的可怕的错误巢等待发生。
使用特定领域的语言,完全用Ruby实现数据文件。
优点:简单和容易。
缺点:没有用户创建的数据是可信的。
我也愿意接受其他不在我可能没有想到的清单上的建议。 安全地实现嵌入数据文件中的脚本的最佳解决方案是什么?
编辑2011年12月23日:添加了DSL的第四个选项,在顶部增加了“附录”并增加了其他想法/背景。
您可以考虑使用Shikashi gem,它允许您创建沙箱并为单个对象定义允许的方法调用的白名单。
考虑使用jRuby而不是Ruby。 Java最初是为了支持移动代码而实现的(回到机顶盒时代),并且有一个经过充分测试的安全模型/实现,我猜可能会包装足够的jRuby,以防止用户脚本/类对其余的游戏系统。 jRuby也支持嵌入,这可能有助于将游戏内核与用户应用程序分开,尽管我不知道它现在有多强壮。
当然,jRuby是Ruby!
链接地址: http://www.djcxy.com/p/95455.html