$SAFE =4 safe enough?

I’m implementing a system where users will be able to execute short
snippets of ruby code and It’ll be executing in a thread with $SAFE
set to 4. From my reading it seems like there have been some
vulnerabilities where users can run some mischevous code. Is this
still the case? I know _why is working on Sandbox but I don’t think I
will have it avaiable in my environment. I’m basically doing something
like the following:

thread = Thread.new do
$SAFE=4
instance_eval(userCode)
end

10 second timeout

if !thread.join(10)
thread.kill
end

That tries to get rid of any potential DOS style attacks. Is there
anything else that could go wrong with this approach?

Farrel

On Aug 29, 2006, at 2:26 PM, Farrel L. wrote:

instance_eval(userCode)
end

10 second timeout

if !thread.join(10)
thread.kill
end

That tries to get rid of any potential DOS style attacks. Is there
anything else that could go wrong with this approach?

999999**99999
Thread.critical = true

There are other things that will DOS a $SAFE = 4 sandbox.


Eric H. - [email protected] - http://blog.segment7.net
This implementation is HODEL-HASH-9600 compliant

http://trackmap.robotcoop.com

On 29/08/06, Eric H. [email protected] wrote:

$SAFE=4
999999**99999

Would undef’ing Thread#criticial= before calling instance_eval help
in this regard?

snacktime [email protected] wrote:

There really isn’t anything you can do to make this safe. Even $SAFE
itself can be set to a different value from the usercode.

No, it can’t. At lower levels it throws a SecurityError saying it
can’t downgrade the safe level. At higher levels, it throws a
SecurityError saying it can’t “can’t chage global variable value”
(i.e. the rules of Level 4 inherently prevent you from changing the
security level.)

There really isn’t anything you can do to make this safe. Even $SAFE
itself can be set to a different value from the usercode. Plus ruby
threads aren’t real threads, so I think someone could just fork off a
new process, or at the least it would be easy to lock up your whole
application by calling some blocking operation that takes forever.

On Aug 30, 2006, at 12:23 AM, snacktime wrote:

There really isn’t anything you can do to make this safe. Even $SAFE
itself can be set to a different value from the usercode.

$SAFE can only be increased.

$ ruby -e ‘$SAFE = 1; $SAFE = 0’-e:1: tried to downgrade safe level
from 1 to 0 (SecurityError)

Plus ruby threads aren’t real threads, so I think someone could
just fork off a
new process,

Not at $SAFE >= 2

$ ruby -e ‘$SAFE = 2; fork do puts “hi” end’
-e:1:in fork': Insecure operation fork’ at level 2 (SecurityError)
from -e:1

or at the least it would be easy to lock up your whole application
by calling some blocking operation that takes forever.

Yes.


Eric H. - [email protected] - http://blog.segment7.net
This implementation is HODEL-HASH-9600 compliant

http://trackmap.robotcoop.com

On 8/30/06, Ken B. [email protected] wrote:

snacktime [email protected] wrote:

There really isn’t anything you can do to make this safe. Even $SAFE
itself can be set to a different value from the usercode.

No, it can’t. At lower levels it throws a SecurityError saying it
can’t downgrade the safe level. At higher levels, it throws a
SecurityError saying it can’t “can’t chage global variable value”
(i.e. the rules of Level 4 inherently prevent you from changing the
security level.)

Ya you are correct, it won’t let you change the safe level. I wonder
how hard it would be to bypass it though using something like
rubyinline?

On Aug 30, 2006, at 1:24 PM, snacktime wrote:

security level.)

Ya you are correct, it won’t let you change the safe level. I wonder
how hard it would be to bypass it though using something like
rubyinline?

Easy for $SAFE <= 3:

$ cat desafe.rb
require ‘rubygems’
require ‘inline’

class DeSafe
inline do |builder|
builder.prefix “RUBY_EXTERN int ruby_safe_level;”

 builder.c <<-EOC
   static void
   reduce() {
     ruby_safe_level = 0;
   }
 EOC

end
end

$SAFE = ARGV.shift.to_i rescue 0

p $SAFE

DeSafe.new.reduce

p $SAFE

$ rm -fr ~/.ruby_inline/; ruby desafe.rb 4
desafe.rb:20:in write': Insecure operation write’ at level 4
(SecurityError)
from desafe.rb:20:in `p’
from desafe.rb:20
$ rm -fr ~/.ruby_inline/; ruby desafe.rb 3
3
0


Eric H. - [email protected] - http://blog.segment7.net
This implementation is HODEL-HASH-9600 compliant

http://trackmap.robotcoop.com