Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to evaluate user expressions in a sandbox

I want my app to evaluate an expression from an untrusted user, that I'll be reading from a JSON file. Such as:

value = "(getTime() == 60) AND isFoo('bar')"

I've found many threads about this here on StackOverflow. Usually recommending using Java's own ScriptEngine class, which can read JavaScript. Or recommending the user to either use an existing library such as JEXL, MVEL, or any other from this list: http://java-source.net/open-source/expression-languages

But they all seem to rely on a trusted user (ex.: a configuration file you write yourself and want to do some scripting in it). But in my case, I want my expression evaluation to run in a secure sandbox. So the user cannot do something as simple as:

value = "while(true)" // or
value = "new java.io.File(\"R:/t.txt\").delete()" // this works on MVEL

And lock up my app, or access unwanted resources.

1) So are any of those existing libraries able to be easily configured so that it can run on a safe box? By 'easily', I mean high level configuration API that would faster for me to use than to write my own expression evaluator. After doing a little bit of my own research, both JEXL and MVEL seem to be out.

2) Or is there an existing expression language that is extremely simple so that it cannot be exploited by an untrusted user? All the ones I found are very complex, and implement things like loops, import statements etc. All I need is to parse math, logic operators and my own defined variables and methods. Anything beyond that is outside of my scope.

3) If the only solution is to write my own expression evaluator, then where can I find some guidance on how to write a consistent security model? I'm new to this, and have no idea of what are the common tricks used for code injection. Which is why I wanted avoid having to write this on my own.

like image 915
VIBrunazo Avatar asked Mar 05 '12 21:03

VIBrunazo


1 Answers

I could recommend embedding Rhino, enabling the user to write javascript. It fits your criteria in (2) perfectly being a java library that enables you to run javascript (or run java from javascript).

You set up a context and the user only has access to what you put in the context or make accessible from it. The javascript expressions can be as simple as the simplest case you show above, or can get as complex as they need to. Embedding Rhino and exposing a limited set of objects was a great way to enable all sorts of user scripting in a past project and that was some years ago, Rhino is quite mature now.

You've also got the advantage that if your problem requires it, you may well be able to set it up so that the same expressions will happily run client or server side.

More information on embedding Rhino to accomplish what you need at http://www.mozilla.org/rhino/tutorial.html#runScript

like image 54
KAB Avatar answered Oct 22 '22 04:10

KAB