安全纳斯霍恩 JS 执行
如何使用Java8 Nashorn安全地执行一些用户提供的JS代码?
该脚本扩展了一些基于 servlet 的报告的计算。该应用程序具有许多不同的(不受信任的)用户。脚本应该只能访问 Java 对象和由定义的成员返回的对象。默认情况下,脚本可以使用 Class.forName() 实例化任何类(使用我提供的对象的 .getClass()。有没有办法禁止访问任何未由我显式指定的java类?
如何使用Java8 Nashorn安全地执行一些用户提供的JS代码?
该脚本扩展了一些基于 servlet 的报告的计算。该应用程序具有许多不同的(不受信任的)用户。脚本应该只能访问 Java 对象和由定义的成员返回的对象。默认情况下,脚本可以使用 Class.forName() 实例化任何类(使用我提供的对象的 .getClass()。有没有办法禁止访问任何未由我显式指定的java类?
对于将 Nashorn 脚本可以创建的类限制为白名单的最佳方法,是否有任何建议?或者这种方法与任何JSR223引擎(ScriptEngineManager构造函数上的自定义类加载器)相同?
从Nashorn的一位开发人员那里得到了这个答案:
你好
Nashorn 已经筛选了类 - 只有非敏感包的公共类(包列在 package.access 安全属性(又名“敏感”)中)。包访问检查是从无权限上下文中完成的。也就是说,只允许从无权限类访问的任何包。
Nashorn 过滤 Java 反射和 jsr292 访问 - 除非脚本有 RuntimePermission(“nashorn.JavaReflection“),脚本将无法进行反射。
上述两个需要在启用 SecurityManager 的情况下运行。在没有安全管理器的情况下,上述筛选将不适用。
您可以在全局范围内删除全局Java.type函数和 Packages对象(+ com,edu,java,javafx,javax,org,JavaImporter)和/或将它们替换为您实现的任何过滤函数。因为,这些是从脚本访问 Java 的唯一入口点,自定义这些函数 = >从脚本中过滤 Java 访问。
有一个未记录的选项(现在仅用于运行test262测试)“--no-java”的nashorn shell可以为您完成上述操作。也就是说,Nashorn不会在全局范围内初始化Java钩子。
JSR223 不提供任何基于标准的钩子来传递自定义类装入器。这可能必须在 jsr223 的(可能)未来更新中解决。
希望这有帮助,
-桑达尔
在 1.8u40 中添加的 ClassFilter
可以限制引擎可以使用的类。
下面是 Oracle 文档中的一个示例:
import javax.script.ScriptEngine; import jdk.nashorn.api.scripting.ClassFilter; import jdk.nashorn.api.scripting.NashornScriptEngineFactory; public class MyClassFilterTest { class MyCF implements ClassFilter { @Override public boolean exposeToScripts(String s) { if (s.compareTo("java.io.File") == 0) return false; return true; } } public void testClassFilter() { final String script = "print(java.lang.System.getProperty(\"java.home\"));" + "print(\"Create file variable\");" + "var File = Java.type(\"java.io.File\");"; NashornScriptEngineFactory factory = new NashornScriptEngineFactory(); ScriptEngine engine = factory.getScriptEngine( new MyClassFilterTest.MyCF()); try { engine.eval(script); } catch (Exception e) { System.out.println("Exception caught: " + e.toString()); } } public static void main(String[] args) { MyClassFilterTest myApp = new MyClassFilterTest(); myApp.testClassFilter(); } }
此示例打印以下内容:
C:\Java\jre8 Create file variable Exception caught: java.lang.RuntimeException: java.lang.ClassNotFoundException: java.io.File