From: Michael Granger Date: 2011-06-10T08:37:16+09:00 Subject: `Kernel.load`ing a file with a class definition in $SAFE = 1 under Ruby 1.9.2-p180 Hi, [I tried posting this to StackOverflow first, so apologies to those for whom this is a double-post of sorts.] I am trying to use the two-argument form of Kernel.load while running in safe level 1 to load a class definition inside an anonymous namespace. For example, the file I'm trying to Kernel.load looks like: # module.rb class Foo < Superclass def bar puts "Bar!" end end And the test case looks like: # loader.rb BASEDIR = File.expand_path( File.dirname(__FILE__) ) MODULE_FILE = File.join( BASEDIR, 'module.rb' ).untaint $stderr.puts "Module file name (%p) is %s" % [ MODULE_FILE, MODULE_FILE.tainted? ? "tainted" : "not tainted" ] class Superclass @subclasses = [] class << self; attr_reader :subclasses; end def self::inherited( subclass ) super @subclasses << subclass end end $stderr.puts "Ruby version: #{RUBY_DESCRIPTION}" $stderr.puts "In $SAFE = 0:" Kernel.load( MODULE_FILE, true ) result = Superclass.subclasses.last p result $stderr.puts "Instantiating and calling its #bar method:" result.new.bar $stderr.puts "In $SAFE = 1:" $SAFE = 1 Kernel.load( MODULE_FILE, true ) result = Superclass.subclasses.last p result $stderr.puts "Instantiating and calling its #bar method:" result.new.bar When I run it under Ruby 1.8.7, the output looks like: Module file name ("/Users/mgranger/source/ruby/misc/safeload/\ module.rb") is not tainted Ruby version: ruby 1.8.7 (2009-06-12 patchlevel 174) \ [universal-darwin10.0] In $SAFE = 0: #::Foo Instantiating and calling its #bar method: Bar! In $SAFE = 1: #::Foo Instantiating and calling its #bar method: Bar! but under 1.9.2-p180, I get a SecurityError: Module file name ("/Users/mgranger/source/ruby/misc/safeload/\ module.rb") is not tainted Ruby version: ruby 1.9.2p180 (2011-02-18 revision 30909) \ [x86_64-darwin10.7.0] In $SAFE = 0: #::Foo Instantiating and calling its #bar method: Bar! In $SAFE = 1: loader.rb:29:in `load': Insecure operation - load (SecurityError) from loader.rb:29:in `
' The documentation for Kernel.load (from rb_f_load() in load.c) says: load(filename, wrap=false) -> true Loads and executes the Ruby program in the file _filename_. If the filename does not resolve to an absolute path, the file is searched for in the library directories listed in $:. If the optional _wrap_ parameter is +true+, the loaded script will be executed under an anonymous module, protecting the calling program's global namespace. In no circumstance will any local variables in the loaded file be propagated to the loading environment. which (at least to me) doesn't contain any clues. If I replace the class definition with a puts or something, it loads fine, but I can't seem to load a class inside an anonymous module any longer. Any ideas? -- Michael Granger Rubymage, Architect, Believer The FaerieMUD Consortium