我想让用户能够编写符号数学公式,这些公式稍后会用特定值进行评估。
例如,用户可能想要输入一些公式 a * (b + 1)
其中 a
和 b
可能不同在每次评估时。到目前为止,我的方法是在 Java 中使用内置的 JavaScript 引擎,但当我通读 this tutorial on scripting 时,我发现这个引擎其实很强大。
公式存储在配置文件中,因此有人可能会将这样的配置文件发送给另一个用户,然后在他们的机器上执行。 不幸的是,我不懂 JavaScript,所以我不知道用户是否真的可以注入(inject)任何严重的恶意代码。
上面的公式将存储为 JavaScriptFormulaProcessor
对象,如下所示:
JavaScriptFormulaProcessor processor =
new JavaScriptFormulaProcessor("a * (b + 1)", "a", "b");
初始化引擎:
public JavaScriptFormulaProcessor(String formula, String... variableNames) throws ScriptException {
ScriptEngine engine = new ScriptEngineManager().getEngineByName("JavaScript");
StringBuilder builder = new StringBuilder(variableNames[0]);
for (int i = 1; i < variableNames.length; i++) {
builder.append(", ").append(variableNames[i]);
}
String script = "function f("+builder.toString()+") { return "+formula+"}";
engine.eval(script);
invocable = (Invocable) engine;
}
执行函数:
public void execute(Number[] functionInputs) throws ScriptException {
try {
Object result = invocable.invokeFunction("f", functionInputs);
// process result..
} catch (NoSuchMethodException e) {
throw new RuntimeException(e); // should actually never be thrown..
}
}
此代码是否会为我的应用程序创建攻击媒介?奖励问题:如果是,有更好的建议吗?
最佳答案
如果 formula
在用户的控制之下,那么这段代码极易受到攻击,因为可以从 ScriptEngine
中访问和运行 Java 方法>.
另见这个问题:Why can you execute Java-Code from a JS-ScriptEngine eval(String)?
例如,考虑这个公式:
String formula = "(java.lang.Runtime.getRuntime().exec('some-malicious-script'), a+b)";
除了计算总和外,此脚本还会运行 java.lang.Runtime.getRuntime().exec()
。
您可以通过这种方式运行任何静态 Java 方法。
关于javascript - 在 Java 中将用户输入评估为 JavaScript 时的安全风险,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35454452/