Executing user-supplied ruby code on a web server Executing user-supplied ruby code on a web server ruby-on-rails ruby-on-rails

Executing user-supplied ruby code on a web server


You can use a "blank slate" as a clean room, and a sandbox in which to set the safe level to 4.

A blank slate an object you've stripped all the methods from:

class BlankSlate  instance_methods.each do |name|    class_eval do      unless name =~ /^__|^instance_eval$|^binding$|^object_id$/        undef_method name      end    end  endend

A clean room is an object in which context you evaluate other code:

  clean_room = BlankSlate.new

Read a command from an untrusted source, then untaint it. Unless untainted, Ruby will refuse to eval the string in a sandbox.

  command = gets  command.untaint

Now execute the string in a sandbox, cranking the safe level up as high as it will go. The $SAFE level will go back to normal when the proc ends. We execute the command in the context of the clean room's binding, so that it can only see the methods and variables that the clean room can see (remember, though, that like any object, the clean room can see anything in global scape).

  result = proc do    $SAFE = 4    clean_room.instance_eval do      binding    end.eval(command)  end.call

print the result:

  p result