aurelianito wrote:
> I want more granularity than what the five (0-4) $SAFE levels offer. I
> want to be able to say  "can write in file A but not in file B"

$ chmod a-w a.txt
$ chmod a+w b.txt


Regarding the method hooks, one thing that you can do to complicate things
somewhat is to do something like this (not tested):

class SomeClass
   def some_method(*a, &b)
     # ...
   end

   alias_method :__safety__, :some_method

   def self.method_added(sym)
     unless @my_add
       # Revert back to original
       if sym == :some_method
         alias_method :some_method, :__safety__
       end
     else
       @my_add = false
     end
   end
end

However, the problem is that the user may simply #undef_method your
#method_added or do something equivalent. It is a neverending cycle.
#freeze helps a bit but there is a way around it, too.

irb(main):001:0> class Foo
irb(main):002:1>   def foo
irb(main):003:2>     puts 'foo'
irb(main):004:2>   end
irb(main):005:1> end
=> nil
irb(main):006:0> Foo.freeze
=> Foo
irb(main):007:0> class Foo
irb(main):008:1>   def foo
irb(main):009:2>     puts 'foo'
irb(main):010:2>   end
irb(main):011:1> end
TypeError: can't modify frozen class
         from (irb):8
irb(main):012:0> x = Foo.dup
=> #<Class:0xb7cef2d4>
irb(main):013:0> Foo = x
(irb):13: warning: already initialized constant Foo
=> Foo
irb(main):014:0> class Foo
irb(main):015:1>   def foo
irb(main):016:2>     puts 'bar'
irb(main):017:2>   end
irb(main):018:1> end
=> nil
irb(main):019:0> Foo.new.foo
bar
=> nil
irb(main):020:0>


The only thing you can do is to modify the Ruby interpreter. You will
need to hook into the method table modification code and intercept all
those calls. Then, for each call, inspect the arguments and no-op any
attempts to modify some defined methods (you should probably allow this
to be configurable).


Or, the simpler solution: A) do not run code that may be malicious and
B) use the operating system's security features such as file permissions

E