$SAFE =4 safe enough?

F

Farrel Lifson

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
 
E

Eric Hodel

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?

999999**99999
Thread.critical = true

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

snacktime

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

Ken Bloom

snacktime said:
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.)
 
S

snacktime

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

Eric Hodel

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

Eric Hodel

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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,470
Messages
2,571,809
Members
48,797
Latest member
PeterSimpson
Top