【发布时间】:2021-08-12 12:55:05
【问题描述】:
我正在开发一个 Java 项目。在其中,我们希望最终用户能够定义基于一组给定的原始类型或字符串变量计算的变量。在某些时候,所有给定的变量都设置为特定的值,然后应该进行计算。然后必须将所有生成的计算变量发送到 Java。
我正在评估最终用户定义计算的方法。 (当前)想法是让他编写 JavaScript 并让该代码在 Java 程序中解释/执行。我知道有两种方法可以做到这一点:使用 javax.scripting API 或 GraalVM/Truffle。在这两种情况下,我们都会这样做:
- 给定的变量被赋予到脚本中。在 javax.scripting 中通过
ScriptEngine.put,在 Graal/Truffle 通过Value.putMember。 - 最终用户可以在全局上下文中定义变量(其名称不得与来自 Java 的名称冲突)。他如何设置它们的值取决于他 - 他可以直接设置它们(到一个常数,到给定变量之一,到其中一些的总和......)或定义对象和函数并通过调用这些来设置值.
- 当给定变量具有固定值时,将执行脚本。
- 脚本在全局上下文中定义的所有变量都将发送到 Java。在 javax.scripting 中通过
ScriptEngine.get,在 Graal/Truffle 通过Value.getMember。
注意:我们不会授予脚本访问任何 Java 类或方法的权限。在 javax.scripting 中通过检查脚本是否包含字符串 Java.type(并禁止这样的脚本),在 Graal/Truffle 中通过使用默认的 Context(具有 allowAllAccess=false)。
互联网上有很多关于 JavaScript 安全问题以及如何避免这些问题的提示和技巧。一方面,我觉得它们都不适用于这里(解释如下)。另一方面,我不太了解 JavaScript - 除了纯粹的、无副作用的计算,我从未将它用于其他任何事情。
所以我在这里寻找一些指导:在这种情况下可能会出现什么样的安全问题?
为什么我在这种情况下看不到任何安全问题:
这是纯 JavaScript。它甚至不允许创建可用于例如在磁盘上创建一个文件。我知道 JavaScript 不包含任何逃避其沙箱的功能(如文件访问、线程、流......),它仅能够操纵提供给其沙箱的数据。见https://262.ecma-international.org/11.0/#sec-overview这部分:
ECMAScript 是一种面向对象的编程语言,用于执行 计算和操作主机内的计算对象 环境。此处定义的 ECMAScript 并非旨在 计算自给自足;确实,没有规定 本规范用于外部数据的输入或计算的输出 结果。 相反,预计 ECMAScript 程序不仅会提供对象和其他 本规范中描述的设施,但也某些 环境特定的对象,其描述和行为是 超出本规范的范围,除非表明它们 可能会提供某些可以访问的属性和某些 可以从 ECMAScript 程序调用的函数。
我们场景中的沙盒只放入一些无害的玩具(即给定的原始类型或字符串变量),在孩子玩过它们(脚本运行)后,生成的建筑物(用户定义的变量) 被取出来保存它们(在 Java 程序中使用)。
【问题讨论】:
标签: javascript java security javax.script graaljs