$SAFE level mutation for tained classes

Hi, fellow Rubyists

What is the rationale behind the following change in SAFE level when
invoking a method with “call”:

class Test
attr_accessor :value
def show
"Safe level: #{$SAFE}"
end
end

Test.taint
t = Test.new

p t.show # ==> Safe level: 0
p t.method(:show).call # ==> Safe level: 4

So every time you invoke a method with “call”, safe level is set to 4
for the duration of the call with all consequences – when you invoke
value= with
t.method(:value=).call(1), you get an error:

ttt.rb:17:in value=': Insecure: can't modify instance variable (SecurityError) from ttt.rb:17:incall’
from ttt.rb:17

Even puts from a so invoked method fails:

ttt.rb:5:in write': Insecure operationwrite’ at level 4
(SecurityError)
from ttt.rb:5:in puts' from ttt.rb:5:inshow’
from ttt.rb:15:in `call’
from ttt.rb:15

I came across this behavior when experimenting with safe level 3, where
all objects are created tainted.

Thanks in advance for any suggestions and/or enlightments.
Gennady.

P.S. I checked in eval.c, there ruby_safe_level is explicitly set to 4
in method_call().

Hi, fellow Rubyists

What is the rationale behind the following change in SAFE level when
invoking a method with “call”:

class Test
attr_accessor :value
def show
“Safe level: #{$SAFE}”
end
end

Test.taint
t = Test.new

p t.show # ==> Safe level: 0
p t.method(:show).call # ==> Safe level: 4

So every time you invoke a method with “call”, safe level is set to 4
for the duration of the call with all consequences – when you invoke
value= with
t.method(:value=).call(1), you get an error:

ttt.rb:17:in value=': Insecure: can't modify instance variable (SecurityError) from ttt.rb:17:in call’
from ttt.rb:17

Even puts from a so invoked method fails:

ttt.rb:5:in write': Insecure operation write’ at level 4
(SecurityError)
from ttt.rb:5:in puts' from ttt.rb:5:in show’
from ttt.rb:15:in `call’
from ttt.rb:15

I came across this behavior when experimenting with safe level 3, where
all objects are created tainted.

Thanks in advance for any suggestions and/or enlightments.
Gennady.

P.S. I checked in eval.c, there ruby_safe_level is explicitly set to 4
in method_call().

Interesting, since Object#send works fine:

class Test
attr_accessor :value
def show
“Safe level: #{$SAFE}”
end
end
=> nil

?> Test.taint
=> Test

t = Test.new
=> #Test:0x401db06c
t.show
=> “Safe level: 0”
t.send :value=, 4
=> 4

···

On Tuesday 28 January 2003 11:44 pm, Gennady wrote:


Bruce R. Williams :: [iusris/#ruby-lang] :: http://www.codedbliss.com

‘It does not require a majority to prevail, but rather an irate,
tireless minority keen to set brush fires in people’s minds.’
– Samuel Adams

Hi,

···

In message “$SAFE level mutation for tained classes” on 03/01/29, Gennady bystr@mac.com writes:

What is the rationale behind the following change in SAFE level when
invoking a method with “call”:

class Test
attr_accessor :value
def show
“Safe level: #{$SAFE}”
end
end

Test.taint
t = Test.new

p t.show # ==> Safe level: 0
p t.method(:show).call # ==> Safe level: 4

Method objects are tainted if they retrieved from tainted objects.
It may be overkill. Let me re-think.

						matz.

Thank you so very much!!! I completely forgot about “send”, I replaced
all my call-s with send-s and now everything works fine. And Matz
mentioned that he might re-think the way “method” works for tainted
objects. So I am covered for the time being with hope for the future :wink:

Gennady.

···

On Tuesday, Jan 28, 2003, at 21:58 US/Pacific, Bruce Williams wrote:

On Tuesday 28 January 2003 11:44 pm, Gennady wrote:

Hi, fellow Rubyists

What is the rationale behind the following change in SAFE level when
invoking a method with “call”:

class Test
attr_accessor :value
def show
“Safe level: #{$SAFE}”
end
end

Test.taint
t = Test.new

p t.show # ==> Safe level: 0
p t.method(:show).call # ==> Safe level: 4

So every time you invoke a method with “call”, safe level is set to 4
for the duration of the call with all consequences – when you invoke
value= with
t.method(:value=).call(1), you get an error:

ttt.rb:17:in value=': Insecure: can't modify instance variable (SecurityError) from ttt.rb:17:in call’
from ttt.rb:17

Even puts from a so invoked method fails:

ttt.rb:5:in write': Insecure operation write’ at level 4
(SecurityError)
from ttt.rb:5:in puts' from ttt.rb:5:in show’
from ttt.rb:15:in `call’
from ttt.rb:15

I came across this behavior when experimenting with safe level 3,
where
all objects are created tainted.

Thanks in advance for any suggestions and/or enlightments.
Gennady.

P.S. I checked in eval.c, there ruby_safe_level is explicitly set to
4
in method_call().

Interesting, since Object#send works fine:

class Test
attr_accessor :value
def show
“Safe level: #{$SAFE}”
end
end
=> nil

?> Test.taint
=> Test

t = Test.new
=> #Test:0x401db06c
t.show
=> “Safe level: 0”
t.send :value=, 4
=> 4


Bruce R. Williams :: [iusris/#ruby-lang] :: http://www.codedbliss.com

‘It does not require a majority to prevail, but rather an irate,
tireless minority keen to set brush fires in people’s minds.’
– Samuel Adams