bulding a crash-proof eval(), is it possible?

N

Nick Brown

I'm building an app which must execute user-submitted bits of Ruby code.
Obviously, eval() does this. Illustration:

user_code = "'hello'.upcase"
result = eval(user_code)
puts "the code evaluated to: " + result

But if the user's code throws an uncaught exception, the whole app
crashes. This can be rectified by wrapping the eval() in
begin/rescue/end:

user_code = "0/0"
begin
result = eval(user_code)
puts "the code evaluated to: " + result
rescue
puts "the code had errors."
end

Unfortunately, it is still possible to make the program crash if the
user code contains syntax errors which interfere with begin/rescue/end.

user_code = "end 'hello there'"
begin
result = eval(user_code)
puts "the code evaluated to: " + result
rescue
puts "the code had errors."
end

The above code will crash the entire application with "syntax error,
unexpected kEND".

So I ask you: is it possible to execute arbitrary user-submitted code in
such a way that the user's code won't crash the server if it contains
innocent mistakes? I am not interested in protecting from malicious
code, just user mistakes.

Alternatively, is it possible to determine whether a given string is
syntactically-correct ruby code? If so, I could simply not eval() such
code.

I welcome any suggestions. Thanks!
 
S

Stefano Crocco

|I'm building an app which must execute user-submitted bits of Ruby code.
|Obviously, eval() does this. Illustration:
|
|user_code = "'hello'.upcase"
|result = eval(user_code)
|puts "the code evaluated to: " + result
|
|But if the user's code throws an uncaught exception, the whole app
|crashes. This can be rectified by wrapping the eval() in
|begin/rescue/end:
|
|user_code = "0/0"
|begin
| result = eval(user_code)
| puts "the code evaluated to: " + result
|rescue
| puts "the code had errors."
|end
|
|Unfortunately, it is still possible to make the program crash if the
|user code contains syntax errors which interfere with begin/rescue/end.
|
|user_code = "end 'hello there'"
|begin
| result = eval(user_code)
| puts "the code evaluated to: " + result
|rescue
| puts "the code had errors."
|end
|
|The above code will crash the entire application with "syntax error,
|unexpected kEND".
|
|So I ask you: is it possible to execute arbitrary user-submitted code in
|such a way that the user's code won't crash the server if it contains
|innocent mistakes? I am not interested in protecting from malicious
|code, just user mistakes.
|
|Alternatively, is it possible to determine whether a given string is
|syntactically-correct ruby code? If so, I could simply not eval() such
|code.
|
|I welcome any suggestions. Thanks!

You need to replace rescue with

rescue Exception

Without any exception classes following it, rescue only rescues exceptions
derived from StandardError.

Stefano
 
E

elise huard

Also, you probably thought of that, but you want stop them from
doing system("rm -rf ~/*") or similar :)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,995
Messages
2,570,230
Members
46,819
Latest member
masterdaster

Latest Threads

Top