Khi một phương pháp được gọi bằng một sợi với $ AN TOÀN = 4, phương pháp mà được chạy với cùng $ mức AN TOÀN:
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
Tuy nhiên, khi một khối được gọi là, có vẻ như sử dụng $ AN TOÀN từ bối cảnh ban đầu của nó thay vào đó:
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
Ai đó có thể giải thích tại sao nó hoạt động theo cách này? Nó có vẻ như một vấn đề an ninh.
(lý do tôi đang sử dụng raise
thay vì puts
là puts
không hoạt động tại $ AN TOÀN = 4)
này có thể được sử dụng để eval một chuỗi nhiễm độc trong bối cảnh dường như an toàn:
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
Sẽ không đóng cửa ghi lại giá trị tại thời điểm xác định? –
Bạn có thể thực hiện các hành động trong khối mà mức '$ SAFE' bằng 0 sẽ cho phép không? –
Andrew: có. Thay thế nội dung của lambda bằng một cái gì đó như 'puts \' hostname \ '' làm cho nó làm chính xác từ bên trong $ SAFE = 4 thread. Tôi hiểu hành vi này từ một phối cảnh phạm vi (kinda) - Tôi chỉ tự hỏi liệu SAFE $ có bị hỏng hoàn toàn trong vấn đề này hay không. – rcrogers