【问题标题】:Ruby: creating a sandboxed eval?Ruby:创建沙盒评估?
【发布时间】:2011-05-20 16:26:23
【问题描述】:

我的 Rails 应用程序对于何时应在页面上显示一些内容有复杂的规则。我决定通过在 Ruby 中编写谓词(简单的“是/否”函数)并将它们存储在数据库中以供后续评估来实现这一点。它非常简单。

我主要关心的是安全性:如果恶意的人知道如何写入数据库,他们可以将任意 Ruby 代码粘贴到数据库中,然后'你所有的基地都属于我们'。

那么是否可以创建一个“沙盒”评估,例如,它已删除所有 IO 操作?

【问题讨论】:

标签: ruby-on-rails ruby eval sandbox


【解决方案1】:

您可能想要检查“污点”方法和相关内容。这是一个很好的参考:

http://ruby-doc.com/docs/ProgrammingRuby/html/taint.html

尽管如此,对于存储代码和评估代码,我不能给出足够多的建议,但这是一个应该避免的安全风险,而且大多数时候有一种更简单的方法可以解决您的问题。

如果您需要评估复杂的规则和谓词,我建议您使用规则引擎来创建一个不错的 DSL。没有在 ruby​​ 中使用过一个,但这个对我来说看起来不错:

http://treetop.rubyforge.org/index.html

干杯

【讨论】:

  • (以及所有):我同意将 eval 代码存储在数据库中是自找麻烦。在这种情况下,我需要动态地添加和删除任意复杂的谓词,其中一个这样的谓词可能是“如果房子大于 2000 平方英尺并且在邮政编码 90210 中并且注册所有者有三辆汽车并且不喜欢紫色的帽子,那是真的'。我可以将谓词硬连接到一个类中,但随后我会不断地进行 git 推送。最终,尽管存在风险,这在 db 中似乎更好。如果您能想到更好的方法,请告诉我!
  • @fearless_fool 嗯好的。我得考虑一下。我希望你内置了足够的错误检查,以防出现语法错误。
  • @fearless_fool,用我认为eval的更好解决方案编辑了这个问题@
  • 我的第一反应是“如果 Ruby 将自己标榜为 DSL 工具,为什么还要编写另一个 DSL?”但我想得越多,就越发现使用 Treetop 或类似工具的智慧:它可以让您完全控制沙盒。
  • 好的,你得到复选标记!我找到了James Coglan's stickup,这是一个使用 Treetop 编写的小型方案解释器,只花了几个小时来学习、扩展它并将其集成到我的应用程序中。是的,这比玩弄 $SAFE 更安全。感谢您的推动!
【解决方案2】:

您可以使用沙盒 gem https://github.com/tario/shikashi 来做到这一点,它允许您将方法列入白名单。
归功于https://stackoverflow.com/a/8704768/188355

【讨论】:

  • 技术上:更像是过去两年的 2 次提交。但它是一个足够小的宝石,一个人可以在需要时支持自己。
  • 是的,我用过,好像还可以。但我现在正在寻找更好的解决方案stackoverflow.com/questions/16267847/…
【解决方案3】:

假设您至少使用 ruby​​ 1.8,您可以在不同的安全级别运行 proc。

def my_unsafe_function
  # possible unsafe stuff
end

proc {
  $SAFE = 4  # change level only inside this proc
  my_unsafe_function
}.call

但是,您应该重新考虑是否真的需要在数据库中存储 ruby​​ 代码。该应用程序的用户是否会修改此存储的代码,为什么?如果不是,为什么不将代码放在应用程序的文件中呢?我不知道你的设置,但应该可以将逻辑移出数据库。

【讨论】:

  • 见上面我对@Pablo 的回复。谓词根据外部因素经常变化。我们可以将它们烘焙到 .rb 文件中,但我们会做很多 git push。 FWIW,是管理员,而不是用户,将修改存储的代码。
  • PS:我忘了说:这是一个在 $SAFE = 4 处运行函数的好结构。
  • 请记住,并非所有 Ruby 实现都完全实现安全(例如,JRuby 不将其视为高优先级),或完美实现 (MRI had a bug)。
  • 这个doesn't work 在 MRI 2.1.0 中:ArgumentError: $SAFE=4 is obsolete
【解决方案4】:

如果你想从你的对象中删除一些方法,你可以检查这个:
remove_methodundef_method

【讨论】:

    猜你喜欢
    • 2020-07-30
    • 2016-07-11
    • 2013-02-07
    • 1970-01-01
    • 1970-01-01
    • 2015-01-19
    • 2016-06-23
    • 1970-01-01
    • 2012-09-02
    相关资源
    最近更新 更多