igul222
igul222

Reputation: 8637

How to safely let users run arbitrary Ruby code?

I realize this sounds a little crazy, but I'm working on a project for which I need a server to run user-provided Ruby code and return the result.

I'm looking to prevent something like this:

system("rm -rf /")
eval("something_evil")
# etc...

I'm sure there must be some reasonably safe way to do this, as it already exists at places like tryruby.org. Any help is greatly appreciated, thanks!

Upvotes: 8

Views: 930

Answers (4)

user2005477
user2005477

Reputation:

I had the same problem but then came across eval.so and decided to write an API wrapper for it, called Sandie. It's as easy as:

sandie = Sandie.new(language: 'ruby')
# => #<Sandie:0x00000002e30650>
sandie.evaluate(code: 'puts "hello world"')
# => {"stdout"=>"hello world\n", "stderr"=>"", "wallTime"=>487, "exitCode"=>0}

It also supports a whole lot of other languages as well like C#, Perl, Lua, and Java.

Upvotes: 0

Wayne Conrad
Wayne Conrad

Reputation: 107979

A "blank slate" is an object stripped of (most of) its methods. A "clean room" is an object within which you evaluate potentially unsafe room. If you evaluate the code in a "clean room" which is also a "blank slate," cranking the safe level up as high as it will go, you will afford yourself a great deal of protection. Nothing in security is sure, so this should be considered a layer in your security, not necessarily the only layer.

This answer shows how to do it.

Upvotes: 2

ig0774
ig0774

Reputation: 41247

Three suggestions:

1) Take a look at Ruby taint levels. This provides some degree of protection against, eval('evil_code') type things, etc.

2) Unless user's actually need access to the local file system, use something like fakefs

3) No matter what else you do follow Tronic's suggestion (can be a pain to setup, but limited chroot jails are about the only way to make absolutely sure that user's cannot access resources you don't explicitly want them to).

Upvotes: 6

Tronic
Tronic

Reputation: 10430

Run the program ptraced with a whitelist of allowed syscalls, as user/group nobody, with resource limits (memory usage etc), in a minimal chroot.

Upvotes: 3

Related Questions