From: Florian Gross Date: 2004-05-13T02:48:55+09:00 Subject: Re: safe eval? ts wrote: > b = safe(' > class << s = "`mv b.rb x.rb`" > def call > end > end > a = Object.new > ObjectSpace.define_finalizer(a, s) > a > ') Heh, I don't actually regard this one as a bug of safe(), but more as one of Ruby. I'm uncertain if matz agrees, however. Personally, I have a more complete version of it that adds $SAFE-checks to a lot of Ruby's built-in methods. (All methods of GC, ObjectSpace.(define|add)_finalizer, Thread.new / .fork / .start / ..critical=, set_trace_func) I'm pretty sure that there are more cases like this where $SAFE isn't checked correctly in Ruby. If anybody wants to point out more of them, I can try to come up with a way to secure them, but I'm unsure if this is the best solution and if it will work all the time. Actually, that's the reason of using a $SAFE-level of 5 and not 4 as one would probably expect. :) Here is the way I secure define_finalizer: ObjectSpace.module_eval do class << self old_finalizer = instance_method(:define_finalizer) define_method(:_define_finalizer) do |block, *args| raise(SecurityError, "Penalizing finalizing") if $SAFE > 1 old_finalizer.bind(self).call(*args, &block) end def define_finalizer(*args, &block) _define_finalizer(block, *args) end alias :add_finalizer :define_finalizer end end If anybody wants to have the complete version with all the other added checks, just let me know. I'll do some cleaning up and release the whole thing in that case. Regards, Florian Gross