On Fri, Feb 6, 2009 at 1:46 PM, Jonathan Wills <runningwild / gmail.com> wrote:
> Christopher Dicely wrote:
>> On Fri, Feb 6, 2009 at 11:55 AM, Jonathan Wills <runningwild / gmail.com>
>> wrote:
>>> can run ruby code.  Basically I want the user to be able to supply an
>>> unspecified number of ruby files, all of which will get run, and not
>>> have to worry about namespace collisions.  Additionally I want access to
>>> the scopes that those files were executed in after they are done.  I
>>> know I can create a binding from my current scope, but if I put anything
>>> in it, it can get modified when I do my_binding.eval.
>>
>> You can get a binding from any object that has a method to tell you
>> its binding. Something like this (off the top of my head) might work:
>> ---
>> class ExecutionContext
>>   private_class_method :new
>>
>>   @@contexts = {}
>>
>>   def self.[](key)
>>     @@contexts[key]
>>   end
>>
>>   def self.new_binding(key)
>>     new(key).binding
>>   end
>>
>>   def initialize(key)
>>     raise KeyError if @@contexts[key]
>>     @@contexts[key] = self
>>   end
>>
>>   def get_binding
>>     binding
>>   end
>> end
>> ---
>>
>> So, when you want a new binding to use, you call
>> ExecutionContext.new_binding(key), and to get back the a binding used
>> previously, you call ExecutionContext[key].get_binding, where "key" is
>> the key given when you called new_binding to generate the binding.
>>
>> But while these are mostly "fresh" bindings, they are nothing at all
>> like safe sandboxes. You may need something like this:
>> http://github.com/why/sandbox/tree/master
>
> Interesting.  Someone else has shown me a similar way of getting a fresh
> context.  Do you know what exactly about it is unlike a sandbox?

The code being eval'd can, as I understand, do anything that a method
on the object providing the binding could do, including, e.g., using
ObjectSpace to mess with any object in the current interpreter
instance, even if it is out of scope of the binding.

>
> Are there any plans for ruby to support a sandboxed eval like I can get
> in python?

I think the use of the trusted/untrusted distinction with $SAFE levels
in Ruby 1.9 may be able to do some, perhaps all, of what you want, but
I haven't done any work with it (just read the description in the Beta
of the new edition of Programming Ruby), so I can't really say. It's
not an eval-specific sandbox, though.