如何锁定(或隔离)JDK内置的Javascript解释器以运行不受信任的脚本。

7
我们有一个Java应用程序,希望使用内置的Javascript解释器(javax.script.*)运行不受信任的代码。然而,默认情况下,解释器允许访问任何Java类。例如,在脚本中使用"java.lang.System.exit(0)"将关闭JVM。我相信这被称为"Live Connect",请参阅Sun的"Java Scripting Programmer's Guide"获取更多详细信息。
我希望以某种方式关闭脚本访问Java类的功能,即我只想让脚本能够访问我使用ScriptEngine上的eval()put()方法明确注入的对象。
我已经找到了一些关于如何在旧版本的独立解释器(Rhino)中实现此目标的文档,例如参见http://codeutopia.net/blog/2009/01/02/sandboxing-rhino-in-java/
但是,在JDK 1.6中,这种方法不可能使用sun内部类,因为ClassShutter等都是内部设置的,不能用公共方法覆盖。
我希望有一种简单的方法来解决这个问题,而不需要通过自定义SecurityManager、ClassLoader等复杂的方法。但是我还没有找到任何东西。
考虑到不同应用程序中围绕Javascript发布的安全公告的频率,你会期望有一个简单的标志来禁用Live Connect!

参见:https://dev59.com/f3M_5IYBdhLWcg3wgzdl - McDowell
我仍然无法相信在2014年,没有一种简单的方法可以禁用Java ScriptEngine的Live Connect。我已经搜索了很久,但没有找到限制访问的简单方法。我正在部署一个服务器端应用程序,它应该能够使用JSR 223解析客户端提供的JavaScript,但如果不能禁用像"java.awt.Desktop.getDesktop()"或"java.lang.System.exit(0)"这样的东西,那么实现几乎是不可能的。 - chrixm
2个回答

1

我搜索了很多并尝试了codeutopia.net的博客沙盒方法和其他SecurityManager解决方案,但感到不满意。然后我提出了自己的类加载器解决方案,基于JDK嵌入式rhino库而不导入任何第三方库。两个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


0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接