7
は方法が$ SAFE = 4とのスレッドによって呼び出されると、そのメソッドは、同じ$ SAFEレベルで実行されます。ブロックが呼び出されたときに
def test_method
raise "value of $SAFE inside the method: #{$SAFE}"
end
t = Thread.new{$SAFE = 4; self.test_method}; t.join
=> RuntimeError: value of $SAFE inside the method: 4
しかし、からの$ SAFEを使用しているようです代わりに元のコンテキスト:
test_lambda = lambda do
raise "value of $SAFE inside the lambda: #{$SAFE}"
end
t = Thread.new{$SAFE = 4; test_lambda.call}; t.join
=> RuntimeError: value of $SAFE inside the lambda: 0
誰かがこのように動作する理由を説明できますか?セキュリティ上の問題のようです。
(私が代わりにputs
のraise
を使用している理由は、puts
は$ SAFEで動作しないということである= 4)これは、一見安全なコンテキストで汚染された文字列をevalに使用することができます
:
test_lambda = lambda{|s| puts "Tainted: #{s.tainted?}"; eval s}
t = Thread.new{$SAFE = 4; test_lambda.call("puts `date`")}; t.join
=> Tainted: true
=> Fri Mar 30 03:15:33 UTC 2012
クロージャは定義時に値を取得しませんか? –
'$ SAFE'レベルの0で許されるアクションをブロック内で実行できますか? –
Andrew:はい。ラムダの内容を 'puts \' hostname \ ''のようなものに置き換えると、$ SAFE = 4スレッド内のものと同じようになります。私はスコープの観点からこの動作を理解しています(ちょっとしたこと) - これに関しては、$ SAFEが完全に壊れているかどうかは分かりません。 – rcrogers