hoodwink.d enhanced


FreakyFreaky Now Resumes Its Usual Sandly Self #

by why in inspect

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)

 # 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.

said on

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..

said on

Not ragging on Sandbox at all—its side of things works. But this particular example isn’t really safe. Imagine:

sand = Sandbox.safe
sand.ref Database
sand.eval("Database.query('DELETE FROM apples')")

unless maybe the Mysql#query method sanitizes the incoming SQL …

said on

lukfugl: Well, sure, it’s up to you to make sure the MySQL user that you use to connect has restricted permissions.

said on

why: Good point. I forgot/overlooked the fact that the user that’s connected to the DB is determined outside the Sandbox.

said on

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:

 class Foo
   def safe() puts "I'm safe!" end
   def unsafe() puts "I'm unsafe!" end

 sand = Sandbox.safe
 sand.ref Foo
 sand.eval "Foo.instance_eval { remove_method :unsafe }" 
said on

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.

said on

Oh, guess I didn’t see that coming. Removing the method in the running environment would work, but wouldn’t be that nice.

said on

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?)

said on

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?

said on

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…

said on

It is all greek to me :)

said on

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.

said on

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?

said on

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`’)

said on

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?

said on

oops. your blog’s code-tag seems broken :)

said on DD Mon YYYY at HH:MM

* do fancy stuff in your comment.