【问题标题】:Executing arbitrary functions in Ruby without the security problems of eval在没有 eval 安全问题的情况下在 Ruby 中执行任意函数
【发布时间】:2013-06-18 10:06:36
【问题描述】:

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

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

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

有没有办法从字符串中对一些变量执行简单的任意逻辑和算术运算并返回一个值?

【问题讨论】:

    标签: ruby-on-rails ruby


    【解决方案1】:

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

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

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

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

    您可以从少量操作(if、算术、逻辑等)开始,然后逐步改进它。最终,您将拥有一个强大的解决方案,该解决方案可以轻松发展以满足用户的需求。

    【讨论】:

      【解决方案2】:

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

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

      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 sandboxing vs. integrating a scripting language

      但即便如此,敞开心扉去面对也是一件可怕的事情。认真对待这一点,并彻底考虑安全隐患。

      【讨论】:

      • 代码仅包含以下内容:if、max、min 和基本算术。这完全是任意的,并且取决于用户,这就是 switch 语句不起作用的原因。
      猜你喜欢
      • 2019-10-01
      • 1970-01-01
      • 2014-06-06
      • 2011-09-06
      • 2017-09-19
      • 2022-06-14
      • 2021-09-10
      • 1970-01-01
      • 2015-07-07
      相关资源
      最近更新 更多