是否可以从 nashorn-engine 隐藏或删除 java api?所以它只能看到或使用带有一些特别暴露的函数/变量的“默认”ECMAScript 262 Edition 5.1?
我想让我的最终用户为他们自己创建一些特定的逻辑,而不用担心他们会破解整个系统。当然,在 nashorn 引擎等中可能存在一些安全漏洞,但这是不同的主题。
编辑:对不起,我忘了提到我在我的 java 应用程序中运行 nashorn,所以不能使用命令行参数。
是否可以从 nashorn-engine 隐藏或删除 java api?所以它只能看到或使用带有一些特别暴露的函数/变量的“默认”ECMAScript 262 Edition 5.1?
我想让我的最终用户为他们自己创建一些特定的逻辑,而不用担心他们会破解整个系统。当然,在 nashorn 引擎等中可能存在一些安全漏洞,但这是不同的主题。
编辑:对不起,我忘了提到我在我的 java 应用程序中运行 nashorn,所以不能使用命令行参数。
以编程方式,您也可以直接使用NashornScriptEngineFactory
具有适当 getScriptEngine() 方法的类:
import jdk.nashorn.api.scripting.NashornScriptEngineFactory;
...
NashornScriptEngineFactory factory = new NashornScriptEngineFactory();
...
ScriptEngine engine = factory.getScriptEngine("-strict", "--no-java", "--no-syntax-extensions");
好的,这是带有一些限制参数的示例类:
package com.pasuna;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Random;
import javax.script.Invocable;
import javax.script.ScriptEngine;
import javax.script.ScriptException;
import jdk.nashorn.api.scripting.NashornScriptEngineFactory;
public class ScriptTest {
public static class Logger {
public void log(String message) {
System.out.println(message);
}
}
public static class Dice {
private Random random = new Random();
public int D6() {
return random.nextInt(6) + 1;
}
}
public static void main(String[] args) {
NashornScriptEngineFactory factory = new NashornScriptEngineFactory();
ScriptEngine engine = factory.getScriptEngine(new String[]{"-strict", "--no-java", "--no-syntax-extensions"});
//note final, does not work.
final Dice dice = new Dice();
final Logger logger = new Logger();
engine.put("dice", dice);
engine.put("log", logger);
engine.put("hello", "world");
try {
engine.eval("log.log(hello);");
engine.eval("log.log(Object.keys(this));");
engine.eval("log.log(dice.D6());"
+ "log.log(dice.D6());"
+ "log.log(dice.D6());");
engine.eval("log.log(Object.keys(this));");
engine.eval("Coffee"); //boom as should
engine.eval("Java"); //erm? shoud boom?
engine.eval("log = 1;"); //override final, boom, nope
engine.eval("log.log(hello);"); //boom
} catch (final ScriptException ex) {
ex.printStackTrace();
}
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String input = "";
do {
try {
input = br.readLine();
engine.eval(input);
} catch (final ScriptException | IOException se) {
se.printStackTrace();
}
} while (!input.trim().equals("quit"));
try {
engine.eval("var add = function(first, second){return first + second;};");
Invocable invocable = (Invocable) engine;
Object result = invocable.invokeFunction("add", 1, 2);
System.out.println(result);
} catch (final NoSuchMethodException | ScriptException se) {
se.printStackTrace();
}
Object l = engine.get("log");
System.out.println(l == logger);
}
}
有关标志的更多信息可以从这里找到:http: //hg.openjdk.java.net/jdk8/jdk8/nashorn/rev/eb7b8340ce3a
(恕我直言,nashorn 文档很差)
You can specify any jjs option for script engines via -Dnashorn.args option when you launch your java program. For example:
java -Dnashorn.args=--no-java Main
where Main uses javax.script API with nashorn engine.
您可以使用 --no-java 选项运行“jjs”工具,以防止脚本对任何显式 Java 包/类进行访问。也就是说,Nashorn 平台是安全的,并使用基于 Java 标准 URL 代码库的安全模型(没有已知 URL 来源的“eval”脚本被视为不受信任、未签名的代码,因此仅获得沙盒权限。
--no-java 是关闭 java 扩展的主要标志。--no-syntax-extensions 关闭非标准扩展。