なんかこんな感じにしたら安全にevalできないかなっていう感じ。
まぁ拾ってきたコードがほとんどなんだけど。
参考
http://tolarian-academy.net/ruby-sandbox-eval-bot/
教えてruby強い人。
ruby
# Sandbox http://tolarian-academy.net/ruby-sandbox-eval-bot/
### usage
# begin
# EvalSandbox.new.execute(code)
# rescue SecurityError, SyntaxError => e
# e.message
# rescue Error => e
# e.message
# end
class EvalSandbox
module Sandbox
[File, Dir, IO, Process, FileTest, RubyVM, RubyVM::InstructionSequence, ObjectSpace].each do |klass|
refine klass.singleton_class do
def banned_method(*_); raise SecurityError.new; end
klass.methods.each do |m|
alias_method(m, :banned_method)
end
end
end
refine Object do
def banned_method(*_); raise SecurityError.new; end
allowed = [:Array, :Complex, :Float, :Hash, :Integer, :Rational, :String, :block_given?, :iterator?, :catch, :raise, :gsub, :lambda, :proc, :rand, :methods]
Kernel.methods.reject { |name| allowed.include?(name.to_sym) }.each do |m|
alias_method(m, :banned_method)
end
end
refine Kernel.singleton_class do
def banned_method(*_); raise SecurityError.new; end
allowed = [:Array, :Complex, :Float, :Hash, :Integer, :Rational, :String, :block_given?, :iterator?, :catch, :raise, :gsub, :lambda, :proc, :rand]
Kernel.methods.reject { |name| allowed.include?(name.to_sym) }.each do |m|
alias_method(m, :banned_method)
end
end
end
def context
binding # Bindingオブジェクトの生成
end
def execute(code, ug)
code = CGI.unescapeHTML(code)
begin
RubyVM::InstructionSequence.compile(code)
rescue SyntaxError => e
return e.message
end
return "Invalid Access" if code.include?("ENV")
begin
safe_code = <<-"CLEANROOM"
module CleanRoom
using Sandbox
#{code}
end
CLEANROOM
eval(safe_code, context)
rescue SecurityError, SyntaxError => e
raise e
rescue Error => e
raise e
end
end
end