I've been toying with an IRC bot that takes input from users in channel,
evals it, and returns the result.

Doing so safely has proved to be a challenge -- the biggest problem
being that you can't trust any method on the returned object.

Here's our solution, and I'd love to know if anyone can break it.

module Safe
  def class
    super
  end
end

def safe_to_s(obj)
  t = Thread.new {
    $SAFE = 4
    obj.to_s
  }
  o = t.value
  class << o
    include Safe
  end
  if String == o.class
    o
  else
    raise SecurityError
  end
end

def safe_eval(code)
  t = Thread.new {
     $SAFE = 4
     eval(code)
  }
  t.value
end

puts(safe_to_s(safe_eval("exit! # or variations")))

puts "Made it!"


Consider this a challenge. The ways I broke simpler variants was to try
to trick safe_to_s into calling methods outside of the safe Thread.

Ari