7

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!

  • See also: http://stackoverflow.com/questions/1347099/how-do-i-secure-scripts-run-using-javax-scripting – McDowell Dec 31 '10 at 16:26
  • I still cannot believe in 2014 there is no easy way to disable Live Connect for Java's ScriptEngine. I have searched and searched without any luck to find an easy way to restrict access. I am deploying a server side application which should be able to parse client provided JavaScript using JSR 223 and without being able to disable things like "`java.awt.Desktop.getDesktop()`" or "`java.lang.System.exit(0)`" it is next to impossible to implement. – chrixm May 13 '14 at 13:08

2 Answers2

1

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.

Arno Mittelbach
  • 944
  • 5
  • 12
1

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