LoginSignup
1
0

More than 3 years have passed since last update.

Rubyで安全にevalしたくて怖いプログラム作った

Last updated at Posted at 2021-02-18

なんかこんな感じにしたら安全に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
1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0