如何在SecurityManager下运行Java 8的nashorn

时间:2014-04-29 05:58:44

标签: security sandbox java-8 nashorn

我正在寻找沙盒Java 8的Nashorn javascript引擎。我已经发现了--no-java标志,这有帮助,但是我也发现了以下链接,说明需要运行安全管理器":{{3 }}

我还没有找到解决如何使用Nashorn完成文档的文档,那么应该如何安全地完成这项工作呢?

3 个答案:

答案 0 :(得分:4)

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

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

jjs -J-Djava.security.manager

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

答案 1 :(得分:4)

我知道你可能不再需要它了,但对于那些在这里寻找一种在沙盒中运行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;
        }
    }
);

答案 2 :(得分: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命令行上的脚本中。 / p>

示例:

$ 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())