Strange safe level change

Eric Hodel wrote:

Well I'm mailing about a problem I'm having while using the rails
framework, since it does seem to be a ruby problem I thought I might
as well post here

I have a security level problem, for unknown reasons it switches
from level 0 to level 4 and then provoke some error related to the
security level...

$SAFE is switched when you assign to it, never at any other time.

Is it so? Consider the following code:

puts RUBY_VERSION, RUBY_PLATFORM

class Test
  def show_safe
    puts $SAFE
  end
end

Test.new.show_safe
Test.new.method(:show_safe).taint.call

It produces:

:!ruby safe.rb
1.8.4
i686-linux
0
safe.rb:5:in `write': Insecure operation `write' at level 4
(SecurityError)
        from safe.rb:5:in `show_safe'
        from safe.rb:12

I have a plugin we developed I that uses a lot of method.call and
apparently according to a post at technoweeny rails forum, this
could be the problem ( RailsNotes, the Ruby on Rails guides you wished you had.
659 ) ...

Is there any way to resolve this problem without having to stop
using method.call (we don't really want a major rewrite) ? What
exactly is the problem and why does it happen?

You have code like $SAFE = 4 in your program somwhere. Use grep to
find it.

Not necessarily. See above.

Typically $SAFE = 4 is only set in a spawned thread since its so
strict its rarely useful outside of sandboxing dangerous code.

Gennady.

···

On Jan 8, 2007, at 22:29, Tom wrote:

Interesting.

You are right. From method_call:

     if (OBJ_TAINTED(method)) {
         safe = NOEX_WITH(data->safe_level, 4)|NOEX_TAINTED;
     }

$SAFE is only changed for the method invocation, it does not leak into the surrounding process. puts $SAFE afterward shows the original safe level.

···

On Jan 9, 2007, at 10:40, Gennady Bystritsky wrote:

Eric Hodel wrote:

On Jan 8, 2007, at 22:29, Tom wrote:

Well I'm mailing about a problem I'm having while using the rails
framework, since it does seem to be a ruby problem I thought I might
as well post here

I have a security level problem, for unknown reasons it switches
from level 0 to level 4 and then provoke some error related to the
security level...

$SAFE is switched when you assign to it, never at any other time.

Is it so? Consider the following code:

Test.new.method(:show_safe).taint.call

It produces:

:!ruby safe.rb
1.8.4
i686-linux
0
safe.rb:5:in `write': Insecure operation `write' at level 4
(SecurityError)
        from safe.rb:5:in `show_safe'
        from safe.rb:12

--
Eric Hodel - drbrain@segment7.net - http://blog.segment7.net

I LIT YOUR GEM ON FIRE!