On Sun, Feb 10, 2013 at 10:45 AM, Ano Hito <[email protected]> wrote:

> Why doesn't ruby ship with a sandbox class?
>
> I know ruby has safe levels, and safe levels do work for many scenarios
> in which you wish to run potentially unsafe code. But they really don't
> offer the same fine grained control that a true sandbox does.

Maybe, that fine grained control you are thinking of is too
complicated to realize - or does not even exist.

> box.eval("a = A.new") #"test"
> box.eval("b = B.new") #fail: I don't know what a "B" is
>
> This is simple, elegant, and far better than setting "$SAFE = 4" and
> hoping for the best.

You make it sound as if people who use $SAFE would not know exactly
how it works.

> Sandboxing is not something that should be left to a third party to
> develop. It belongs in the core of the language if it belongs anywhere
> at all. So why isn't it? Personally I have a few theories.
>
> It could be that the ruby devs think safe levels are good enough. I
> would buy this, except safe levels are a very inelegant and unrubylike
> solution to a problem for which a much simpler solution could exist.
> Need to mess with something unsafe? Just throw it in the box. Why use
> constructs like "taintedness" when you could just throw them out in
> favor of something more effective and flexible, but less complicated.

It remains to be seen whether the alternatives are really simpler.

> But maybe they think nobody needs or even wants sandboxing? I'm sure a
> lot of people don't, but sometimes you never know how useful something
> can be until you have the option of using it. As much as sandboxing
> could become a bad solution to many common problems, it is still the
> only solution to a set of less common problems.

I am not a regular user of $SAFE and at the moment I have no idea what
use cases you are referring to here.  Can you share some more detail,
please?

> Personally I think the
> number of problems that are unsolvable with a language is always
> something worth reducing.

I wouldn't say always.  All changes come with a cost.  If the cost is
too high then the reduction of unsolvable problems is not worthwhile.

> Especially if it might also serve to simplify
> things that are currently implemented in a complex way.

If that is the case, then, yes, I agree.

> What I can tell you is that
> at the very least, if I was building a ruby implementation from scratch,
> I know how I'd do it.
>
> Here's how it would work. As opposed to having a single object space for
> everything, we allow for the creation of multiple object spaces
> (ObjectSpace.new). Every thread would then be attached to the object
> space it was created it, so that anything you did in that thread would
> exist in a separate world from anything happening in another object
> space. You could use objectspace.eval to make stuff happen in any object
> space for which you have a reference. If you want to put something in an
> object space, you can call objectspace.ref a_thing, and it now exists in
> that object space too. Sort of...
>
> To implement this properly you'd need a wrapper class (SharedObject).
> Then when you called sandboxspace.ref object, it would create a instance
> of a wrapper for the object that would exist only in sandboxspace, but
> would use the same object id of the original object. The wrapper would
> contain only a single send method which would temporarily switch the

Did you mean #method_missing instead of #send?

> objectspace of the current thread (an ability that would of course not
> be allowed for normal ruby code), create wrappers for any objects being
> sent as parameters, and then send them to the method being called.

I think there are some issues with wrappers.  Assuming object X lives
in object space A and was thrown into objectspace B.  Y and Z are
other objects private to object space B.

1. A method call from Y to X which passes Z as argument would
implicitly export Z to A.  For a sandbox it would not make sense to
_implicitly_ export something to another box (object space).

2. How far in the object graph starting at Z do you want to go with
wrapper creation?  It's not that you only export Z to A but also a
whole lot other objects.  This is not only a security issue (item 1)
but also a performance issue because you would need a recursive wrap
of all objects.

3. How do you ensure objects stay inside their boxes if you
automatically create wrappers for method arguments?  It seems the
situation is not that different as with a single global object space.

The situation would be easier if you allowed for object graphs
starting at method arguments only objects which are known to the
target object space, i.e. disallow implicit migration.  I am not so
sure though whether that solution is so far away from $SAFE - or
creating separate processes which communicate via DRb.

> I think this would be a very good approach that would offer ruby a much
> more flexible security model that it currently has. If only I had the
> time or experience with ruby's code base to implement it... All I can do
> is offer my approach as a suggestion. But maybe it will get the ball
> rolling, get people talking, that kind of stuff.

I believe your suggestion certainly needs more thinking.  Before we
talk about implementations we should clarify requirements - even more
so as this is a security topic.

> Remember, you'll never be able to justify calling it
> ruby 2.0 unless you have lots of cool new features to play with. ;)

I am pretty sure it's too late to include such a fundamental
architectural change into Ruby 2.0.  That sounds more like a Ruby 3.0
thing.

Kind regards

robert


-- 
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/

-- 
[email protected] | 
https://groups.google.com/d/forum/ruby-talk-google?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"ruby-talk-google" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.


Reply via email to