FreakyFreaky Now Resumes Its Usual Sandly Self #
I know it’s been out of sorts for the past month, but the big checkin is, in fact, IN. The big deal today: class and module references.
svn co http://code.whytheluckystiff.net/svn/sandbox/trunk sandbox cd sandbox ruby setup.rb
Like, say you want to give a sandbox some limited access to a database:
require 'sandbox' require 'mysql' # setup a proxy module module Database @@db = Mysql.connect(...) def self.query(str) @@db.query(str).fetch_hash end end # use the proxy module inside the sandbox sand = Sandbox.safe sand.ref Database sand.eval("Database.query('SELECT * FROM apples')")
Well, this is a bit contrived. But, you know?
And it’s safe. In the sandbox, the Database module is actually a Database class, descended from BoxedClass, which has a method_missing
which will restore the original Ruby environment, make the call, and marshal the results back to the sandbox. So the query call in the box does get its Hash.
Peter Cooper
Ooh, now that’s nice. I’ve been developing something using the Sandbox and created my own DRb-a-like that I run within a Sandbox so that sandboxed code can call a carefully defined set of possibly ‘unsafe’ classes. With this I can probably get rid of all that and just make the classes of my choice available directly. Shall have fun looking at this stuff..
lukfugl
Not ragging on Sandbox at all—its side of things works. But this particular example isn’t really safe. Imagine:
unless maybe the Mysql#query method sanitizes the incoming SQL …
why
lukfugl: Well, sure, it’s up to you to make sure the MySQL user that you use to connect has restricted permissions.
lukfugl
why: Good point. I forgot/overlooked the fact that the user that’s connected to the DB is determined outside the Sandbox.
rruneh
That is great! I was actually looking for how to import “crippled” versions of classes to a sandbox. Now it should be as easy as:
why
You’ll need to do more than that. The attacker could still call
Foo.method_missing(:unsafe)
. Yeah, I’ll work on a version of remove_method that does it right.rruneh
Oh, guess I didn’t see that coming. Removing the method in the running environment would work, but wouldn’t be that nice.
MenTaLguY
Calling remove_method inside the Sandbox won’t do anyway, since evil code in the sandbox could always redefine it.
(yeah, you’re fine as long as you never ever ref any classes into the sandbox after untrusted code runs in it, but aren’t you going to need to do that sometimes?)
J. F. Miller
Ah, it’s good to see the FFSB back in the front page. A while back someone tried to get this to work on Windows, but I haven’t seen anything recently. Can anyone give me a hint of how to get a this up an running on my Win32 system?
roberthahn
Is there a link to a resource that explains how attackers can even do bad things like this to other people’s code? B/c right now I’m having trouble comprehending the need for this class…
german
It is all greek to me :)
why
J. F. Miller: Windows builds have been dropped momentarily. Until the next major Ruby release or I can get a patched one compiled. Support for gems has been dropped permanently, since the FF doesn’t mix well with them.
roberthahn: It’s for stuff like Try Ruby or Ning where you want to allow people to run scripts inside your application, but you want to control what they can do.
murphy
why: please don’t hit me or something ^^ but I’m interested in performance.
how much is the overhead when I call Sanbox#eval? would it be a good idea to define more abstract methods inside the BoxedModule that do a lot of work in one call, for example?
Peter Cooper
Just realized I’ll need to kill send methods on remote classes. When you pull them in you can still do things like this:
SomeClass.send(:eval, ’`ls`’)
cupe
hi i am trying to ref a class containing an array:
class Foo @@bar = ["f", "o", "o"] def bar() @@bar end end box.ref Foo box.eval("Foo.bar")
this doesn’t seem to work as the sandbox is giving me an “Array can’t be referred (Sandbox::Exception)”
any ideas about how to get my array into the box?
cupe
oops. your blog’s code-tag seems broken :)