在Ruby中执行任意函数,没有eval的安全问题



我有一个Ruby on Rails应用程序,我需要添加一些任意的'函数'到数据库。这些函数需要接收预定义的参数,执行任意的逻辑和算术,并返回一个数字或字符串。

我的第一个想法是将代码添加到DB并使用eval(code),但我很快意识到这样做的安全问题。我找不到一个真正的沙盒eval的方法。

我还考虑过使用JavaScript解释器,例如,在JS中使用代码并在自己的上下文中运行它,但它似乎仍然有点太多,不够安全。

是否有一种方法来执行简单的任意逻辑和算术从字符串在一些变量和返回一个值?

运行任意代码是一种不安全的做法,并且很难确保您控制所有变量和不同的场景。

你可以尝试修补所有可以运行任何恶意代码的Ruby类/模块,如IO, Kernel等,但最终你会有许多类修补,非常难以维护,并且不确定它是否会安全工作。

我能想到的最好的解决方案是创建你自己的编程语言,你可以确保所有的功能和操作都是用户可以访问的。

现在有许多解决方案,论文和示例使这项任务不那么困难,例如编译成Ruby的Ragel http://www.complang.org/ragel/。

您可以从少量操作(if,算术,逻辑等)开始,然后逐步改进。最后,您将拥有一个健壮的解决方案,可以轻松地发展以适应用户需求。

这段代码需要多复杂?或者反过来说,它需要有多任意?希望您不需要存储代码。

相反,保持代码在代码中,数据在数据中。然后简单地引用过程的名称。例如:

class User
  def contact
    case self.prefers_contact_method
    when :email
      Email.send_to self.email
    when :sms
      SMS.send_to self.mobile_number
    when :call
      Phone.place_call self.home_number
    end
  end
end

将可执行代码放在数据库中不是一个好主意。不惜一切代价避免它。如果你真的需要这样做,那么也许你应该重新考虑你的方法。


如果你真的真的需要这样做,你需要一个沙盒。在某种环境中,您可以控制任意代码可以访问的内容,这样就不会有可能执行的危险代码。参见:Ruby沙箱vs.集成脚本语言

但即便如此,敞开心扉也是一件可怕的事情。对此要非常小心,并彻底考虑安全含义。

最新更新