Sandbox's Init and Import
mfp: This makes me think that the point of sandbox is not as much allowing access to stuff you cannot use with higher $SAFE levels as offering a clean environment. Am I right? In both cases, being able to specify which stuff is to be imported could be useful.
Starting with an example:
box = Sandbox.new(:init => [:load], :import => [:YAML, :File]) box.eval("require 'rubygems'")
This is conceptual, it doesn’t yet work all the way. The
init option loads a portion of Ruby’s core into the sandbox. It doesn’t actually load a shared lib or anything. It just allows access to some C methods (or hacked versions of them) built into the Sandbox extension.
:init => [:load] is kind of like when
Init_load from eval.c gets call. That call gives you
$LOADED_FEATURES and the like. There should only be five or so of these init modules. From there you can
remove_method anything you don’t want around.
:import will copy classes from the main Ruby interpreter into the Sandbox. This is a deep copy which will recursively import modules, classes, singleton classes and methods until we hit
Object or anything the sandbox already has. Oh and then instance variables get marshalled. I gotta remember to do that.
I wouldn’t recommend this approach for restricted sandboxes and I will probably disable it for the most restrictive subclass. In those cases you’ll want to just pass in a string to be eval’d. That gives only one object reference as a hook to the outside and it’s trapped in C.