Language in a Sandbox in Rails

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.

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".

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: 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

A scripting engine for Ruby?

There's also Rufus-lua though it's at version 0.1.0...



Related Topics



Leave a reply



Submit