Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How stop Nashorn from allowing the quit() function?

Tags:

nashorn

I'm trying to add a scripting feature to our system where untrusted users can write simple scripts and have them execute on the server side. I'm trying to use Nashorn as the scripting engine.

Unfortunately, they added a few non-standard features to Nashorn:

https://docs.oracle.com/javase/8/docs/technotes/guides/scripting/nashorn/shell.html#sthref29

Scroll down to "Additional Nashorn Built-in Functions" and see the "quit()" function. Yup, if an untrusted user runs this code, the whole JVM shuts down.

This is strange, because Nashorn specifically anticipates running untrusted scripts. See: https://docs.oracle.com/javase/8/docs/technotes/guides/scripting/nashorn/api.html#classfilter_introduction

Applications that embed Nashorn, in particular, server-side JavaScript frameworks, often have to run scripts from untrusted sources and therefore must limit access to Java APIs. These applications can implement the ClassFilter interface to restrict Java class access to a subset of Java classes.

Is there any way to prevent this behavior? How do I prevent users from running any of the additional functions?

like image 535
ccleve Avatar asked Jun 30 '15 00:06

ccleve


2 Answers

Unfortunately, there is currently no way to control creation of non-standard global functions. One workaround is to simply delete these functions from the global object after the ScriptEngine has been initialized:

final NashornScriptEngineFactory engineManager = new NashornScriptEngineFactory();
final ScriptEngine engine = engineManager.getScriptEngine();
final Bindings bindings = engine.getBindings(ScriptContext.ENGINE_SCOPE);
bindings.remove("print");
bindings.remove("load");
bindings.remove("loadWithNewGlobal");
bindings.remove("exit");
bindings.remove("quit");
System.err.println(engine.eval("'quit is ' + typeof quit"));

If you are using the Nashorn shell, a simple delete quit; will do.

If you are using the ScriptEngine interface and create multiple bindings, you'll have to do this with every global object/binding you create.

like image 55
Hannes Wallnöfer Avatar answered Sep 22 '22 10:09

Hannes Wallnöfer


If you're going to run "untrusted" scripts, please run your program with the SecurityManager turned on. With that "quit" would have resulted in SecurityException. ClassFilter by itself is not a replacement for SecurityManager. It is used to be used along with the SecurityManager. Please check the JEP on ClassFilter here: http://openjdk.java.net/jeps/202. The JEP clearly states this:

Make security managers redundant for scripts. Embedding applications should still turn on security management before evaluating scripts from untrusted sources. Class filtering alone will not provide a complete script "sandbox." Even if only untrusted scripts (with no additional Java classes) are executed, a security manager should still be utilized. Class filtering provides finer control beyond what a security manager provides. For example, a Nashorn-embedding application may prevent the spawning of threads from scripts or other resource-intensive operations that may be allowed by security manager.

like image 30
A. Sundararajan Avatar answered Sep 21 '22 10:09

A. Sundararajan