# $SAFE =4 safe enough?

**URL:** <https://www.ruby-forum.com/t/safe-4-safe-enough/66873>\
**Category:** Ruby\
**Created:** [August 29, 2006, 11:26pm UTC](https://www.ruby-forum.com/t/safe-4-safe-enough/66873 "2006-08-29T23:26:53Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![Farrel\_L](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/f/9d8465/32.png) [@Farrel\_L](https://www.ruby-forum.com/u/Farrel_L)\
**Post date:** [August 29, 2006, 11:26pm UTC](https://www.ruby-forum.com/t/safe-4-safe-enough/66873/1 "2006-08-29T23:26:53Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![Farrel\_L](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/f/9d8465/32.png) [@Farrel\_L](https://www.ruby-forum.com/u/Farrel_L)\
**Post date:** [August 29, 2006, 11:46pm UTC](https://www.ruby-forum.com/t/safe-4-safe-enough/66873/2 "2006-08-29T23:46:55Z")

</div>

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. - removed\_email\_address@domain.invalid - [http://blog.segment7.net](http://blog.segment7.net)  
This implementation is HODEL-HASH-9600 compliant

[http://trackmap.robotcoop.com](http://trackmap.robotcoop.com)

---

<div class="post-metadata">

**Author:** ![Farrel\_L](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/f/9d8465/32.png) [@Farrel\_L](https://www.ruby-forum.com/u/Farrel_L)\
**Post date:** [August 30, 2006, 8:48am UTC](https://www.ruby-forum.com/t/safe-4-safe-enough/66873/3 "2006-08-30T08:48:13Z")

</div>

On 29/08/06, Eric H. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> > $SAFE=4  
> > 999999\*\*99999

Would undef’ing Thread#criticial= before calling instance\_eval help  
in this regard?

---

<div class="post-metadata">

**Author:** ![Farrel\_L](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/f/9d8465/32.png) [@Farrel\_L](https://www.ruby-forum.com/u/Farrel_L)\
**Post date:** [August 30, 2006, 9:36pm UTC](https://www.ruby-forum.com/t/safe-4-safe-enough/66873/4 "2006-08-30T21:36:02Z")

</div>

snacktime [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) 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.)

---

<div class="post-metadata">

**Author:** ![Farrel\_L](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/f/9d8465/32.png) [@Farrel\_L](https://www.ruby-forum.com/u/Farrel_L)\
**Post date:** [August 30, 2006, 9:24am UTC](https://www.ruby-forum.com/t/safe-4-safe-enough/66873/5 "2006-08-30T09:24:15Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![Farrel\_L](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/f/9d8465/32.png) [@Farrel\_L](https://www.ruby-forum.com/u/Farrel_L)\
**Post date:** [August 31, 2006, 2:16am UTC](https://www.ruby-forum.com/t/safe-4-safe-enough/66873/6 "2006-08-31T02:16:39Z")

</div>

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. - removed\_email\_address@domain.invalid - [http://blog.segment7.net](http://blog.segment7.net)  
This implementation is HODEL-HASH-9600 compliant

[http://trackmap.robotcoop.com](http://trackmap.robotcoop.com)

---

<div class="post-metadata">

**Author:** ![Farrel\_L](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/f/9d8465/32.png) [@Farrel\_L](https://www.ruby-forum.com/u/Farrel_L)\
**Post date:** [August 30, 2006, 10:26pm UTC](https://www.ruby-forum.com/t/safe-4-safe-enough/66873/7 "2006-08-30T22:26:08Z")

</div>

On 8/30/06, Ken B. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> snacktime [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) 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?

---

<div class="post-metadata">

**Author:** ![Farrel\_L](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/f/9d8465/32.png) [@Farrel\_L](https://www.ruby-forum.com/u/Farrel_L)\
**Post date:** [August 31, 2006, 2:22am UTC](https://www.ruby-forum.com/t/safe-4-safe-enough/66873/8 "2006-08-31T02:22:39Z")

</div>

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. - removed\_email\_address@domain.invalid - [http://blog.segment7.net](http://blog.segment7.net)  
This implementation is HODEL-HASH-9600 compliant

[http://trackmap.robotcoop.com](http://trackmap.robotcoop.com)
