From: Andy Morrow Date: 2007-04-04T02:51:10+09:00 Subject: Bug in ERb when using $SAFE>=4 I've been working with ERB and trying to run it in a secure environment. (My goal is to allow end users to render templates in my Rails app.) There is what appears to me to be a bug in ERB when you try to run an object that was created with $SAFE >= 4. Here's the relevant code: (from erb.rb in class ERB starting on line #735) def result(b=TOPLEVEL_BINDING) if @safe_level th = Thread.start { $SAFE = @safe_level eval(@src, b, (@filename || '(erb)'), 1) #problem } return th.value else return eval(@src, b, (@filename || '(erb)'), 1) end end The problem lies in passing TOPLEVEL_BINDING to eval. Once $SAFE>=4 is set, a new binding is created and you're no longer allowed to modify the original binding. There's no option to pass eval the binding created after $SAFE is set inside the new thread. My modified version of the code reads like this: (from erb.rb in class ERB, line # 739) eval(@src, (@safe_level==4? binding : b), (@filename || '(erb)'), 1) #no problem any more I've tested this a million times, and you can't pass ERB a valid binding unless you set $SAFE>=4 in your main app (and I can't do that.) Am I just crazy? Did I miss something? Thanks, Andy Morrow