【问题标题】:How to create a sandboxed RSpec environment?如何创建沙盒 RSpec 环境?
【发布时间】:2012-08-06 03:42:27
【问题描述】:

本质上,我想创建一个程序,该程序将运行一些定义某些方法或类的不受信任的代码,然后针对它运行不受信任的 rspec 规范。

我对沙盒 Ruby 进行了一些研究,来自 ruby​​conf 的 this video 特别有用。在查看了几个解决方案之后,似乎最有帮助的两个是rubycop,它本质上是对代码进行静态分析,以及jruby sandbox(两者都在上面的视频中介绍过)。我的直觉告诉我,jruby 沙盒可能更安全,但我很可能错了。

这是我想做的一个完全不安全的例子:

code = <<-RUBY
class Person
  def hey
    "hey!"
  end
end
RUBY

spec = <<-RUBY
describe Person do
  let(:person) { Person.new }

  it "says hey" do
    person.hey.should == "hey!"
  end
end
RUBY

# code and spec will be from user input (unsafe)

eval code
require 'rspec/autorun'
eval spec

这一切都很好,但代码显然需要沙盒。几分钟后某个天才会提交system("rm -rf /*")fork while fork 或同样危险的东西。

我对 jruby 沙箱做了各种尝试...

sand = Sandbox::Safe.new
sand.eval("require 'rspec/autorun'")
sand.activate! # lock it down
sand.eval code
puts sand.eval spec

该代码抛出此异常:

Sandbox::SandboxException: NoMethodError: undefined method `require' for #<RSpec::Core::Configuration:0x7c3cfaab>

这是因为 RSpec 在沙盒被锁定后试图要求一些东西。

所以,我试图通过调用空的describe 来强制 RSpec 在沙箱被锁定之前要求一些东西:

sand = Sandbox::Safe.new
sand.eval("require 'rspec/autorun'")
sand.eval("describe("") { }")
sand.activate! # lock it down
sand.eval code
sand.eval spec

我明白了:

Sandbox::SandboxException: NameError: uninitialized constant RSpec

这基本上意味着RSpec 不存在于沙盒中。这很奇怪,考虑到 sand.eval("require 'rspec/autorun'") 返回 true,并且前面的示例确实有效(RSpec 的自动加载器开始运行)。

这可能是 gems 和这个特定沙箱的问题。沙盒对象实际上支持#require方法,本质上是绑定Kernel.require,因此无法加载gem。

开始看起来使用这个沙盒可能无法通过 rspec 实现。主要问题是试图将其实际加载到沙箱中。我什至尝试过这样的事情:

require 'rspec'
sand.ref(RSpec) # open access to local rspec

但它没有。

所以,我的问题有两个:

  • 是否有人对如何让它与 jruby 沙箱一起工作有什么好主意?
  • 如果不是,rubycop 的安全性如何?显然codeschool 使用它,所以它必须经过很好的测试......能够使用 ruby​​ 1.9 而不是 jruby 也很好。

【问题讨论】:

    标签: ruby rspec jruby sandbox


    【解决方案1】:

    沙盒环境似乎没有加载包/gemset。如果您使用 gemset 或其他东西,RVM 可能会出现问题。

    一旦沙盒化,人们可能会尝试再次加载捆绑包。

    我会看看 ruby​​ 污点模式

    $SAFE   The security level
    0 --> No checks are performed on externally supplied (tainted) data. (default)
    1 --> Potentially dangerous operations using tainted data are forbidden.
    2 --> Potentially dangerous operations on processes and files are forbidden.
    3 --> All newly created objects are considered tainted.
    4 --> Modification of global data is forbidden.
    

    【讨论】:

      【解决方案2】:

      我一直在尝试找出类似的问题。激活后,我想在我的沙箱中使用 json 和 rest-client 之类的 gem。我试过了。

      require "sandbox"
      s=Sandbox.safe
      
      s.eval <<-RUBY
        require 'bundler'
        Bundler.require :sandbox
      RUBY
      
      s.activate!
      

      Gemfile.rb

      group :sandbox do
        platforms :jruby do
          gem 'json'
          gem 'rest-client'
        end
      end
      

      这样,我就可以在我的沙盒中使用 gems。但是,沙盒存在一些特定于宝石的问题。例如,我必须在 jruby-sandbox 中为 safe.rb 添加一个方法 initialize_dup 到白名单中。 RestClient 对我正在尝试修补的假文件系统 ALT_SEPARATOR 有一些问题。您可以对 RSpec 尝试这种方法,看看是否一切正常。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-03-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-16
        • 1970-01-01
        • 1970-01-01
        • 2013-01-13
        相关资源
        最近更新 更多