How to create a RSpec sandbox?

Essentially, I want to create a program that will run some untrusted code that defines a method or class, and then run an untrusted rspec specification.

I looked into the Ruby sandbox a bit, and this video from rubyconf was especially useful. After looking at a few solutions, two that seem most useful, rubycop , which essentially does static code analysis, and jruby sandbox (both are included in the video above). My instinct tells me that the jruby sandbox is probably safer, but I could have been mistaken.

Here's a completely unsafe example of what I want to do:

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 , .

, RSpec - , , describe:

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 ).

. sandbox #require, Kernel.require .

, rspec. . - :

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

.

, :

+5
2

, /gemset. RVM , gemset - .

.

taint-

$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.
0

. , json rest-client . .

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

, . , . , initialize_dup safe.rb jruby-sandbox. RestClient Fake File Sytem ALT_SEPARATOR, . RSpec , .

0

All Articles