首页 文章

如何阻止Nashorn允许quit()函数?

提问于
浏览
5

我正在尝试向我们的系统添加脚本功能,其中不受信任的用户可以编写简单的脚本并让它们在服务器端执行 . 我正在尝试使用Nashorn作为脚本引擎 .

不幸的是,他们为Nashorn添加了一些非标准功能:

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

向下滚动到“Additional Nashorn Built-in Functions”并查看“quit()”函数 . 是的,如果不信任的用户运行此代码,整个JVM将关闭 .

这很奇怪,因为Nashorn特别期望运行不受信任的脚本 . 见:https://docs.oracle.com/javase/8/docs/technotes/guides/scripting/nashorn/api.html#classfilter_introduction

嵌入Nashorn的应用程序,特别是服务器端JavaScript框架,通常必须从不受信任的源运行脚本,因此必须限制对Java API的访问 . 这些应用程序可以实现ClassFilter接口,以限制Java类访问Java类的子集 .

有什么方法可以防止这种行为吗?如何阻止用户运行任何其他功能?

2 回答

  • 3

    不幸的是,目前无法控制非标准全局函数的创建 . 一个解决方法是在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"));
    

    如果您使用的是Nashorn shell,那么就可以使用简单的 delete quit; .

    如果您正在使用ScriptEngine接口并创建多个绑定,则必须对您创建的每个全局对象/绑定执行此操作 .

  • 7

    如果您要运行"untrusted"脚本,请在安装了SecurityManager的情况下运行您的程序 . 因此"quit"会导致SecurityException . ClassFilter本身不是SecurityManager的替代品 . 它用于与SecurityManager一起使用 . 请在这里查看ClassFilter上的JEP:http://openjdk.java.net/jeps/202 . JEP明确指出:

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

相关问题