ruby-on-rails - Ruby\Rails 沙箱

标签 ruby-on-rails ruby

我有一个案例,当来自 DB 字段的文本应该在沙盒模式下“评估”时 - 使用方法和常量的白名单,允许调用。

gem https://github.com/tario/shikashi非常适合这个,但在我看来,它被遗弃了。

我什至不能运行 Basic Example 2(只有 Basic Example 1 可以正常工作):

require "rubygems"
require "shikashi"

include Shikashi

def foo
    # privileged code, can do any operation
    print "foo\n"
end

s = Sandbox.new
priv = Privileges.new

# allow execution of foo in this object
priv.object(self).allow :foo

# allow execution of method :times on instances of Fixnum
priv.instances_of(Fixnum).allow :times

#inside the sandbox, only can use method foo on main and method times on instances of Fixnum
s.run(priv, "2.times do foo end")

因为它失败并出现错误 Cannot invoke method foo on object of class Object (SecurityError)

这个 gem 使用另一个 gem evalhook 来解决这个问题,它看起来很复杂。还有另一个像这个这样的 gem ,但它们被遗弃得更多。

据我所知,使用 $SAFE 并不是一个好主意,因为它存在漏洞。

是否有其他方法可以实现此类功能?也许使用 Binding 对象进行操作?

最佳答案

我的问题在没有任何 gem 的情况下并不难解决。这个想法是你有方法和常量的白名单 WHITELIST 并且这个类检查,如果所有的方法和常量都在白名单中

# gem install 'parser'

require 'parser/current'

class CodeValidator
  attr_reader :errors, :source

  WHITELIST = {:send => [:puts, :+, :new], :const => [:String]}

  class Parser::AST::Node
    def value
      return children[1] if [:send, :const].include? type
      fail NotImplementedError
    end
  end


  def initialize(source)
    @errors = []
    @source = source
  end

  def valid?
    !insecure_node?(root_node)
  end

  private

  def exclude_node?(node)
    blacklisted_node_types.include?(node.type) && !WHITELIST[node.type].include?(node.value)
  end

  def blacklisted_node_types
    WHITELIST.keys
  end

  def insecure_node?(node)
    return !!add_error_for_node(node) if exclude_node?(node)
    node.children.each { |child_node| return true if child_node.class == Parser::AST::Node && insecure_node?(child_node) }
    false
  end

  def root_node
    @root_node ||= Parser::CurrentRuby.parse source
  end

  def add_error_for_node(node)
    errors << "#{node.type} not allowed: #{node.value}"
  end
end

c = CodeValidator.new("s = 'hello ' + String.new('world'); puts s.inspect")
p c.valid? # => false
p c.errors # => ["send not allowed: inspect"]

关于ruby-on-rails - Ruby\Rails 沙箱,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32054127/

相关文章:

ruby-on-rails - CSV 导入问题

ruby-on-rails - 为什么我的测试没有通过?

ruby - 如何在安全的沙箱中运行不受信任的 Ruby 代码?

mysql - 使用 sidekiq 扩展 ruby​​ 脚本以将数据存储在 MySQL 中?

ruby-on-rails - rails:为#<StateMachine::Machine:0xba3014ec> 调用了 protected 方法 `around_validation'

ruby-on-rails - 如何处理XMLRPC::FaultException errors?

ruby-on-rails - Rack 中间件中的跟踪错误

ruby-on-rails - 如何测试 cucumber 的错误?

ruby - 正则表达式保留所需的字符串并删除其他字符串

ruby-on-rails - 如何在 Rails 2.3 中测试多态 Controller ?