Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to lock down (or sandbox) JDK's built-in Javascript interpreter to run untrusted scripts

we have a Java application and would like to run untrusted code using the built in Javascript interpreter (javax.script.*)

However by default the interpreter allows access to any java class. For example "java.lang.System.exit(0)" in the script will shutdown the JVM. I believe this is called "Live Connect", see Sun's "Java Scripting Programmer's Guide" for more details.

I would like to somehow turn off the ability for the script to access Java classes, i.e. I only want the script to be able to access objects that I specifically inject in using the eval() or put() methods on ScriptEngine.

I have found some documentation on how to achieve this with older standalone version of the interpreter (Rhino), for example see http://codeutopia.net/blog/2009/01/02/sandboxing-rhino-in-java/

However this approach is not possible in JDK 1.6 without using sun internal classes, as the ClassShutter etc is all setup internally and cannot be overridden with public methods.

I am hoping there is a simple way around this that does not require jumping through complex hoops using a custom SecurityManager, ClassLoader, etc. but have not been able to find anything.

You would expect with the frequency of security bulletins surrounding Javascript in different applications, there would be a simple flag to disable Live Connect!

like image 251
Brett Vasconcellos Avatar asked Jan 27 '10 23:01

Brett Vasconcellos


2 Answers

Have a look at the java sandbox library and the post on how to do exactly what you want for groovy (http://blog.datenwerke.net/2013/06/sandboxing-groovy-with-java-sandbox.html). Rhino can be tackled in a similar fashion.

like image 187
Arno Mittelbach Avatar answered Sep 21 '22 15:09

Arno Mittelbach


I searched a lot, tried out codeutopia.net's blog sandboxing way and other SecurityManager solutions, felt unsatisfied. And then came out my class loader solution, basing on JDK embedded rhino library without importing any 3rd-parties libraries. Two java classes with about 200 lines of codes, it is currently my simplest solution that fits my JavaScript only requirement.

  1. Find out JavaScript script engine factory class name by ScriptEngineManager#getEngineFactories
  2. Load script engine factory class in a new class loader, in which JavaMembers or other related classes will be ignored.
  3. Call #getScriptEngine on loaded script engine factory and eval scripts on returned script engine.

If given script contains Java script, class loader will try to load JavaMembers or other classes and trigger class not found exceptions. In this way, malicious scripts will be ignored without execution.

Please read ConfigJSParser.java and ConfigJSClassLoader.java files for more details:

https://github.com/webuzz/simpleconfig/tree/master/js/im/webuzz/config

like image 23
zhourenjian Avatar answered Sep 19 '22 15:09

zhourenjian