we have a Java application and would like to run untrusted code using the built in Java开发者_运维知识库script 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!
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.
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.
- Find out JavaScript script engine factory class name by ScriptEngineManager#getEngineFactories
- Load script engine factory class in a new class loader, in which JavaMembers or other related classes will be ignored.
- 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
精彩评论