Ruby沙箱与集成脚本语言 [英] Ruby sandboxing vs. integrating a scripting language

查看:96
本文介绍了Ruby沙箱与集成脚本语言的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在使用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

我已经看过三个四个选项,但是我不确定哪种方法最好:

  1. 使用Ruby脚本,但在某种类型的沙箱中.

    优点::非常熟悉Ruby,不需要胶水"代码或在语言之间集成对象的问题.

    缺点:对安全性问题或沙箱不太熟悉,还没有找到任何合适的即用型解决方案.

  2. 实现嵌入另一种脚本语言,例如卢阿.

    优点::Ruby和Lua是基于C的,因此绑定应相当简单. Lua是一种相当流行的语言,因此如果以后遇到问题,可以提供帮助.安全,因为脚本未提供我未明确绑定的任何功能.

    缺点::现有的Ruby-Lua绑定似乎是单向的,陈旧且维护不善,或者两者兼而有之.似乎很狡猾,无法将一种脚本语言嵌入另一种脚本语言中.

  3. 使用Ruby解释器实现自定义脚本语言.我一直在尝试 Treetop ,并且编写一个足以满足脚本要求的简单语法应该不难. /p>

    优点::无需嵌入其他语言.脚本只能使用我专门实现的功能.

    缺点:过度杀伤力. 此处未建"综合症.可能可怕的错误等待发生.

  4. 使用特定于域的语言完全在Ruby中实现数据文件.

    优点:简单易行.

    缺点:用户创建的数据不可信任.

我也愿意接受我可能没有想到的其他建议.安全实施嵌入在数据文件中的脚本的最佳解决方案是什么?

编辑2011年12月23日::在DSL中添加了第四个选项,并在顶部添加了附录"以及其他想法/背景.

解决方案

您可以考虑使用 Shikashi gem ,它允许您创建沙箱并在单个对象上定义允许的方法调用的白名单.

I am currently working on a text-based game engine in Ruby, with the app separated into Ruby code in /lib and YAML data in /data, which is loaded when needed by the game. I want to allow the data files to contain basic scripts, mostly in an event/observer model. However, I also want users to be able to generate and share custom scenarios without having to worry about malicious code embedded in the script.

Addendum: My original plan was to have user-created content separated into two types, "modules" which were data-only (and thus safe) and plugins which added additional functionality (but obviously were not safe). To make an analogy to tabletop gaming, modules would be like published adventure scenarios and content, and plugins would be rulebooks containing additional rules and systems.

Sample script (syntax of course subject to change based on solution):

---
Location:
  observers:
    on_door_open: |
      monster = spawn_monster(:goblin);
      monster.add_item(random_item());
      monster.hostile = true;

From a security standpoint, it would be ideal if scripting was strictly opt-in, probably through an included mixin with a little DSL, e.g.:

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

I've looked at three four options, but I'm not sure which is the best approach to take:

  1. Use Ruby scripting, but in a sandbox of some kind.

    Pros: Very familiar with Ruby, no need for "glue" code or issues integrating objects between languages.

    Cons: Not very familiar with security issues or sandboxing, haven't found any out-of-the-box solutions that seem to fit.

  2. Implement Embed another scripting language, e.g. Lua.

    Pros: Ruby and Lua are C-based, so bindings should be reasonably simple. Lua is a reasonably popular language, so help available if I run into issues later. Secure, since any functionality I don't specifically bind will be unavailable from scripts.

    Cons: Existing Ruby-Lua bindings seem to be one-way, old and poorly maintained, or both. Seems a mite dodgy to embed a scripting language inside another scripting language.

  3. Implement a custom scripting language with Ruby interpreter. I've been experimenting with Treetop, and it shouldn't be too hard to make a simple grammar that would suffice for the scripts.

    Pros: No need to embed another language. Only functionality I've specifically implemented will be available to scripts.

    Cons: Overkill. "Not built here" syndrome. Probably horrible nest of bugs waiting to happen.

  4. Implement the data files entirely in Ruby, using a domain-specific language.

    Pros: Simple and easy.

    Cons: No user-created data is trustable.

I am also open to other suggestions not on that list that I may not have thought of. What is the best solution to safely implement scripts embedded in data files?

Edit 2011年12月23日: Added fourth option with DSL, added "addendum" at top with additional thoughts/context.

解决方案

You might consider using the Shikashi gem, which allows you to create sandboxes and define a whitelist of allowed method calls on individual objects.

这篇关于Ruby沙箱与集成脚本语言的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆