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
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!
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!
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)
.
, :