Ruby: Creating a Sandboxed Eval

Ruby: creating a sandboxed eval?

You might want to check the 'taint' method and related stuff. This is a good reference:

http://ruby-doc.com/docs/ProgrammingRuby/html/taint.html

Despite that, I can't advise you enough against storing code and evaluating it, it's a security risk that should be avoided and most times there's a simpler way of solving your problems.

If you need to evaluate complex rules and predicates I'd recommend a rule engine to create a nice DSL. Haven't used one in ruby but this one looks good to me:

http://treetop.rubyforge.org/index.html

Cheers

How to run untrusted Ruby code inside a safe sandbox?

$SAFE is not enough; you need to be at least at the level of Why's freaky sandbox. However, I don't know if that sandbox code is actively maintained or if he/they ever solved the holes such as infinite loops, etc.

Unsafe generally means hostile. If you can relax from hostile to, say, 'naive', and depending upon the requirements of your app, you might get away with sandboxing in Ruby. It's not really a first-class scenario in the language design.

Even with that, though, you probably don't need to go to the machine level of separation. I'd feel pretty safe using a sandbox in a separately spawned process, with your app functioning as a process manager to kill off any that manage to hang/flame. Now, that is a few orders of magnitude more work than your simple block above.

But remember and keep repeating, "SAFE can't deal with hostile".

Executing arbitrary functions in Ruby without the security problems of eval

Run arbitrary code it is a unsafe practice and very difficult to ensure that you control all variables and different scenarios.

You can try to patch all Ruby classes/ modules that can run any malicious code, like IO, Kernel, etc, but in the end you will have many classes patched, very difficult to maintain and will not have sure if it will work safely.

The best solution that I can figure out is to create your own programming language where you can ensure all functions and operations that the user will have access.

Nowadays there are many solutions, paper and examples that makes this task not so difficult, for example Ragel http://www.complang.org/ragel/ that compiles to Ruby.

You can start with few operations (if, arithmetic, logic, etc) and improve it incrementally. In the end, you will have a robust solution that can easily evolve to fit on users needs.

Ruby\Rails sandboxing

My problem was not so hard to solve without any gems. The idea is that you have whitelist of methods and constants WHITELIST and this class checks, if all methods and constants are in the whitelist

# gem install 'parser'

require 'parser/current'

class CodeValidator
attr_reader :errors, :source

WHITELIST = {:send => [:puts, :+, :new], :const => [:String]}

class Parser::AST::Node
def value
return children[1] if [:send, :const].include? type
fail NotImplementedError
end
end


def initialize(source)
@errors = []
@source = source
end

def valid?
!insecure_node?(root_node)
end

private

def exclude_node?(node)
blacklisted_node_types.include?(node.type) && !WHITELIST[node.type].include?(node.value)
end

def blacklisted_node_types
WHITELIST.keys
end

def insecure_node?(node)
return !!add_error_for_node(node) if exclude_node?(node)
node.children.each { |child_node| return true if child_node.class == Parser::AST::Node && insecure_node?(child_node) }
false
end

def root_node
@root_node ||= Parser::CurrentRuby.parse source
end

def add_error_for_node(node)
errors << "#{node.type} not allowed: #{node.value}"
end
end

c = CodeValidator.new("s = 'hello ' + String.new('world'); puts s.inspect")
p c.valid? # => false
p c.errors # => ["send not allowed: inspect"]

Ruby sandboxing vs. integrating a scripting language

You might consider using the Shikashi gem, which allows you to create sandboxes and define a whitelist of allowed method calls on individual objects.



Related Topics



Leave a reply



Submit