7

我们有一个 Java 应用程序,希望使用内置的 Javascript 解释器 (javax.script.*) 运行不受信任的代码

但是默认情况下,解释器允许访问任何 java 类。例如java.lang.System.exit(0)脚本中的 " " 将关闭 JVM。我相信这被称为“Live Connect”,有关详细信息,请参阅 Sun 的“Java Scripting Programmer's Guide”。

我想以某种方式关闭脚本访问 Java 类的能力,即我只希望脚本能够访问我使用eval()put()方法专门注入的对象ScriptEngine

我找到了一些关于如何使用较旧的独立版本的解释器(Rhino)实现这一点的文档,例如参见http://codeutopia.net/blog/2009/01/02/sandboxing-rhino-in-java/

然而,如果不使用 sun 内部类,这种方法在 JDK 1.6 中是不可能的,因为 ClassShutter 等都是在内部设置的,不能用公共方法覆盖。

我希望有一种简单的方法可以解决这个问题,不需要使用自定义的 SecurityManager、ClassLoader 等跳过复杂的环节,但找不到任何东西。

您会期望随着不同应用程序中围绕 Javascript 的安全公告的频率出现,会有一个简单的标志来禁用 Live Connect!

4

2 回答 2

1

看看java 沙箱库和关于如何为 groovy 做你想要的事情的帖子(http://blog.datenwerke.net/2013/06/sandboxing-groovy-with-java-sandbox.html)。犀牛可以用类似的方式解决。

于 2013-07-01T16:27:20.060 回答
1

搜索了很多,尝试了codeutopia.net的博客沙盒方式和其他SecurityManager解决方案,感觉不太满意。然后推出了我的类加载器解决方案,基于 JDK 嵌入式 rhino 库,无需导入任何 3rd-party 库。两个 java 类,大约 200 行代码,它是目前我最简单的解决方案,适合我的 JavaScript 唯一要求。

  1. 通过 ScriptEngineManager#getEngineFactories 找出 JavaScript 脚本引擎工厂类名
  2. 在新的类加载器中加载脚本引擎工厂类,其中 JavaMembers 或其他相关类将被忽略。
  3. 在加载的脚本引擎工厂上调用 #getScriptEngine 并在返回的脚本引擎上调用脚本。

如果给定的脚本包含 Java 脚本,类加载器将尝试加载 JavaMembers 或其他类并触发类未找到异常。这样,恶意脚本将被忽略而不执行。

请阅读 ConfigJSParser.java 和 ConfigJSClassLoader.java 文件了解更多详情:

https://github.com/webuzz/simpleconfig/tree/master/js/im/webuzz/config

于 2015-07-15T14:38:29.120 回答