4

我正在寻找沙盒 Java 8 的 Nashorn javascript 引擎。我已经发现了 --no-java 标志,这很有帮助,但我还发现以下链接说需要“在启用 SecurityManager 的情况下运行”: http: //mail.openjdk.java.net/ pipermail/nashorn-dev/2013-September/002010.html

我还没有找到说明如何使用 Nashorn 完成此操作的文档,那么应该如何安全地完成此操作?

4

3 回答 3

5

我知道您可能不再需要它了,但是对于那些来这里寻找一种在沙箱中运行 nashorn 的简单方法的人:如果您只想阻止脚本使用反射,请设置一个 ClassFilter。这样,您可以只允许使用一些可用的类......或者根本不使用。

NashornScriptEngineFactory factory = new NashornScriptEngineFactory();
ScriptEngine scriptEngine = factory.getScriptEngine(
    new String[] { "--no-java" }, //a quick way to disable direct access to java API
    null, //a ClassLoader, let's just ignore it
    new ClassFilter() { //this one simply forbids use of any java classes, including reflection
        @Override
        public boolean exposeToScripts(String string) {
            return false;
        }
    }
);
于 2016-10-24T07:14:51.833 回答
4

jjs可以在启用安全管理器的情况下执行脚本。

jjs -J-Djava.security.manager myscript.js

或者

jjs -J-Djava.security.manager

用于交互模式。请注意,如果您只使用 -Djava.security.manager,则该选项将由 jjs 工具处理。要将选项传递给 VM,您必须使用 -J 前缀。除启动器工具“java”之外的任何其他 JDK bin 工具都是如此。

于 2014-06-23T11:02:24.353 回答
2

java命令不同,似乎无法通过在命令行上设置java.security.manager属性来启用安全管理器。jjs(这可能是一个错误。)但是,您可以从 JavaScript 调用 Java API 来启用安全管理器。在 Java 中,这是

System.setSecurityManager(new SecurityManager());

在 JavaScript/Nashorn 中它几乎是一样的,除了你提供完全限定的类名:

java.lang.System.setSecurityManager(new java.lang.SecurityManager())

(或者,您可以导入名称。)您可以将此行放入您的应用程序脚本中,也可以将其放入您在jjs应用程序脚本之前放置在命令行中的脚本中。

例子:

$ cat userhome.js
print(java.lang.System.getProperty("user.home"))
$ jjs userhome.js
/Users/xyzzy
$ cat secmgr.js
java.lang.System.setSecurityManager(new java.lang.SecurityManager())
$ jjs secmgr.js userhome.js
Exception in thread "main" java.security.AccessControlException: access denied ("java.util.PropertyPermission" "user.home" "read")
    at java.security.AccessControlContext.checkPermission(AccessControlContext.java:457)
    [...snip...]

但是,在命令行上设置策略文件确实有效:

$ cat all.policy
grant {
    permission java.security.AllPermission;
};
$ jjs -Djava.security.policy=all.policy secmgr.js userhome.js
/Users/xyzzy

或者您可以setProperty在启用安全管理器之前添加等效调用:

$ cat secmgr.js
java.lang.System.setProperty('java.security.policy', 'all.policy')
java.lang.System.setSecurityManager(new java.lang.SecurityManager())
于 2014-06-21T18:43:30.573 回答