2015-06-30 45 views
3

我试图添加一个脚本功能,我们的系统不受信任的用户可以写简单的脚本,并让他们在服务器端执行。我试图使用Nashorn作为脚本引擎。如何阻止Nashorn允许quit()函数?

不幸的是,他们增加了一些非标准的功能,犀牛:

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

向下滚动到“其他犀牛内置函数”,看到了“退出()”函数。是的,如果不受信任的用户运行此代码,则整个JVM将关闭。

这是奇怪的,因为犀牛特别是预计运行不可信的脚本。请参阅:https://docs.oracle.com/javase/8/docs/technotes/guides/scripting/nashorn/api.html#classfilter_introduction

应用嵌入了犀牛,尤其是服务器端JavaScript 框架,经常有来自不受信任来源的运行脚本,因此必须 限制访问的Java API。这些应用程序可以通过 实现ClassFilter接口来将Java类的访问权限限制为Java类的一个 子集。

有什么办法来防止这种行为?如何防止用户运行任何附加功能?

+0

你一定要开始一个新的进程来运行不可信用户的代码。但也见... http://stackoverflow.com/questions/24466203/how-to-remove-java-apis-from-nashorn-engine – kervin

+0

谢谢,这是一个非常有用的链接。但是没有选择来阻止quit()。我尝试了{“-strict”,“--no-java”,“--no-syntax-extensions”,“--optimistic-types = true”}和quit()仍然退出。 – ccleve

回答

6

不幸的是,目前还没有办法控制的非标准全局函数创建。一个解决办法是简单地从全局对象中删除这些功能,该ScriptEngine已被初始化后:

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")); 

如果您使用的是犀牛壳,一个简单的delete quit;会做。

如果您正在使用的ScriptEngine接口,并创建多个绑定,你必须与每一个全局对象要做到这一点/结合创建。

3

如果你要运行“不可信”的脚本,请运行您的程序与安全管理器打开。用“退出”会导致SecurityException。 ClassFilter本身并不是SecurityManager的替代品。它用于与SecurityManager一起使用。请在这里检查ClassFilter上的JEP:http://openjdk.java.net/jeps/202。 JEP明确指出:

使安全管理器成为脚本冗余。在评估来自不受信任来源的脚本之前,嵌入式应用程序仍应开启安全管理。单独的类过滤不会提供完整的脚本“沙箱”。即使只执行不受信任的脚本(没有附加的Java类),仍应该使用安全管理器。类过滤提供了超出安全管理器提供的更好的控制。例如,Nashorn嵌入式应用程序可能会阻止从安全管理器可能允许的脚本或其他资源密集型操作产生线程。

相关问题