$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

999999**99999
Thread.critical = true

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

···

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

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?

--
Eric Hodel - drbrain@segment7.net - http://blog.segment7.net
This implementation is HODEL-HASH-9600 compliant

http://trackmap.robotcoop.com

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

···

On 29/08/06, Eric Hodel <drbrain@segment7.net> wrote:

On Aug 29, 2006, at 2:26 PM, Farrel Lifson wrote:
> 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.

--
Eric Hodel - drbrain@segment7.net - http://blog.segment7.net
This implementation is HODEL-HASH-9600 compliant

http://trackmap.robotcoop.com

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.

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

···

snacktime <snacktime@gmail.com> wrote:

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.

--
Ken Bloom. PhD candidate. Linguistic Cognition Laboratory.
Department of Computer Science. Illinois Institute of Technology.
http://www.iit.edu/~kbloom1/

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.

···

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

--
Eric Hodel - drbrain@segment7.net - http://blog.segment7.net
This implementation is HODEL-HASH-9600 compliant

http://trackmap.robotcoop.com

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 8/30/06, Ken Bloom <kbloom@gmail.com> wrote:

snacktime <snacktime@gmail.com> 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.)

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

···

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

On 8/30/06, Ken Bloom <kbloom@gmail.com> wrote:

snacktime <snacktime@gmail.com> 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?

--
Eric Hodel - drbrain@segment7.net - http://blog.segment7.net
This implementation is HODEL-HASH-9600 compliant

http://trackmap.robotcoop.com