Ruby on rails Ruby:创建沙盒评估?

Ruby on rails Ruby:创建沙盒评估?,ruby-on-rails,ruby,eval,sandbox,Ruby On Rails,Ruby,Eval,Sandbox,我的Rails应用程序有复杂的规则,关于什么时候页面上应该显示一些内容。我决定通过在Ruby中编写谓词(简单的“是/否”函数)并将它们存储在db中以供后续评估来实现这一点。这很简单 我主要担心的是安全性:如果一个恶意的人知道如何写入数据库,他们可能会在数据库中插入任意的Ruby代码,然后“你所有的基础都属于我们” 那么,是否可以创建一个“沙盒”评估,例如,它删除了所有IO操作 您可能需要检查“污染”方法和相关内容。这是一个很好的参考: 尽管如此,我还是建议您不要存储代码并对其进行评估,这是一种

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

我主要担心的是安全性:如果一个恶意的人知道如何写入数据库,他们可能会在数据库中插入任意的Ruby代码,然后“你所有的基础都属于我们”


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

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

尽管如此,我还是建议您不要存储代码并对其进行评估,这是一种应该避免的安全风险,大多数情况下,有一种更简单的方法来解决您的问题

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


干杯

如果要从对象中删除某些方法,可以选中此项:

或者

假设您至少使用了ruby 1.8,您可以在不同的安全级别上运行程序

def my_unsafe_function
  # possible unsafe stuff
end

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

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

您可以使用沙箱gem来实现这一点,它允许您将方法列为白名单。

归功于

(以及所有):我同意在数据库中存储评估代码是自找麻烦。在这种情况下,我需要动态地添加和删除任意复杂的谓词,其中一个谓词可能是“如果房子的面积大于2000平方英尺,邮政编码为90210,注册车主有三辆车,不喜欢紫色帽子,则为true”。我可以将谓词硬连接到一个类中,但之后我将继续进行git推送。最终,尽管存在风险,但在db中这似乎更好。如果你能想出更好的办法,请告诉我@无畏的傻瓜,好的。我得考虑一下。“我希望你有足够的错误检查,以防出现语法错误之类的问题。”无畏的傻瓜,用我认为更好的方法编辑了这个问题,我的第一反应是“如果Ruby自诩为DSL工具,为什么还要编写另一个DSL呢?”但我越想它,就越能看到使用Treetop或类似工具的智慧:它让你完全控制沙箱。好吧,你得到了复选标记!我找到了一个用Treetop编写的小型scheme解释器,只花了几个小时就学会了它,扩展了它,并将它集成到我的应用程序中。是的,这是一种比玩弄$SAFE更安全的方法。谢谢你的轻推!见我对上面@Pablo的回复。谓词根据外部因素频繁变化。我们可以将它们烘焙到.rb文件中,但我们会进行大量git推送。FWIW,修改存储代码的是管理员,而不是用户。PS:我忘了提到:这是一个很好的构造,可以在$SAFE=4下运行函数。请记住,并非所有Ruby实现都完全实现SAFE(例如,JRuby不将其视为高优先级),也不是完美地实现它().这在MRI 2.1.0中:
ArgumentError:$SAFE=4已经过时了
这里的一些好的响应,导致了可能的重复。同意这闻起来像是的重复。FWIW,接下来的问题()可能是真正的答案,换句话说,使用专用DSL。技术上:更像是过去两年中的两次提交。但这是一块足够小的宝石,一个人可以在需要的时候支撑自己。是的,我用过了,看起来还可以。但我现在正在寻找更好的解决方案