Running a Featureful Sandbox

Although many people associate a sandbox as tamper-proof housing for insecure code, it's also a great way to make new Ruby environments. Imagine what could be done:

  • Require many different versions of a library, each in their own sandbox.
  • Load Rails applications into separate sandboxes.
  • Glue together code by different coders without concern of conflict.

Kicking Off Just Such a Sandbox

 #!ruby
 box = Sandbox.new :init => :all
 box.eval(code_string)

This sandbox initializes the :all built-in module, a whole new Ruby interpreter with classes for File, IO, environment variables, globals. In short, all that's missing from the safe sandbox.

You can also choose to load only portions of Ruby:

  • :env: environment variables and streams (STDOUT, STDIN, etc.)
  • :io: the IO, File, File::Stat and Dir classes.
  • :load: the load and require methods, along with $LOAD_PATH and $LOADED_FEATURES.
  • :real: the GC and ObjectSpace modules, along with abort, exit and the RUBY_* constants.

Many modules can be loaded by passing in an array.

 #!ruby
 box = Sandbox.new :init => [:io, :env]

Calling Into the Sandbox

Unlike the SafeSandbox, this sandbox doesn't marshal objects coming out of the sandbox. So, you can alter objects and use them outside the sandbox. Since Ruby resolves many references during parsing, most code will be able to work it out.