How to evaluate custom expressions in a sandbox

I want my application to evaluate an expression from an untrusted user that I will read from a JSON file. For instance:

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

I found many threads about this here at StackOverflow. It is generally recommended that you use your own ScriptEngine Java class, which can read JavaScript. Or, recommend the user to 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 rely on a trusted user (for example: a configuration file that you write yourself and want to make some scripts). But in my case, I want my expression evaluation to be done in a secure sandbox. Thus, the user cannot do something simply:

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

And block my application or gain access to unwanted resources.

1) So is it possible to easily configure any of these existing libraries so that it can work in a safe window? Easy, I mean a high-level configuration API that would use me faster than writing my own expression evaluator. Having done a bit of my own research, both JEXL and MVEL do not seem to work.

2) Or is there an existing expression language that is extremely simple so that it cannot be used by an untrusted user? Everything I found is very complex and implements things like loops, import operations, etc. All I need to do is analyze the mathematical, logical operators and my own specific variables and methods. Everything beyond this is beyond my scope.

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

+6
source share
1 answer

I could recommend embedding Rhino, allowing the user to write javascript. It meets your criteria in (2), perfectly representing a java library that allows you to run javascript (or run java from javascript).

You set the context, and the user has access only to what you put in the context, or make available from it. Javascript expressions can be as simple as the simplest case you show above, or can be as complex as necessary. Implementing Rhino and providing a limited set of objects was a great way to include all kinds of custom scripts in a previous project, and that was a few years ago, but Rhino is now ripe.

You also have the advantage that if your problem requires this, you can configure it so that the same expressions happily run on the client or server side.

More information on implementing Rhino to achieve what you need, http://www.mozilla.org/rhino/tutorial.html#runScript

+1
source

Source: https://habr.com/ru/post/910028/


All Articles