ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

在Java中使用JS 以及 sandbox

2022-05-14 18:02:26  阅读:313  来源: 互联网

标签:Java 字节 JavaScript JS 编译 sandbox 引擎 使用


说明

此篇主要记录在Java 中使用js 的风险,以及使用sandbox来解决可能出现的rce问题。

1、ScriptEngine的使用

从JDK6开始,java就嵌入了对脚本的支持,这里的脚本指的是但非局限于JS这样的非java语言,当时使用的脚本执行引擎是基于Mozilla 的Rhino。该引擎的特性允许开发人员将 JavaScript 代码嵌入到 Java 中,甚至从嵌入的 JavaScript 中调用 Java。此外,它还提供了使用jrunscript从命令行运行 JavaScript 的能力。
Java ScriptEngine优缺点:
优点:可以执行完整的JS方法,并且获取返回值;在虚拟的Context中执行,无法调用系统操作和IO操作,非常安全;可以有多种优化方式,可以预编译,编译后可以复用,效率接近原生Java;所有实现ScriptEngine接口的语言都可以使用,并不仅限于JS,如Groovy,Ruby等语言都可以动态执行。
缺点:无法调用系统和IO操作 ,也不能使用相关js库,只能使用js的标准语法。更新:可以使用scriptengine.put()将Java原生Object传入Context,从而拓展实现调用系统和IO等操作。

1.1 JavaScript 引擎

从JDK 8开始,Nashorn取代Rhino成为Java的嵌入式JavaScript引擎。
Nashorn完全支持ECMAScript 5.1规范以及一些扩展。它使用基于JSR 292的新语言特性,其中包含在JDK 7中引入的invokedynamic,将JavaScript编译成Java字节码。
nashorn首先编译javascript代码为java字节码,然后运行在jvm上,底层也是使用invokedynamic命令来执行,所以运行速度很给力。
Nashorn是一个纯编译的JavaScript引擎
它没有用Java实现的JavaScript解释器,而只有把JavaScript编译为Java字节码再交由JVM执行这一种流程,跟Rhino的编译流程类似。

[ JavaScript源码 ] -> ( 语法分析器 Parser ) -> [ 抽象语法树(AST) ir ] -> ( 编译优化 Compiler ) -> [ 优化后的AST + Java Class文件(包含Java字节码) ] -> JVM加载和执行生成的字节码 -> [ 运行结果 ]

只从JVM以上的层面看,Nashorn是一种单层的纯编译型JavaScript实现。所有JavaScript代码在首次实际执行前都会被编译为Java字节码交由JVM执行。(当然JVM自身可能是混合执行模式的,例如HotSpot VM与J9 VM。所以Nashorn在实际运行中可能需要一定预热才会达到最高速度)

验证过程如下:
下属通过代码的方式,验证当前Jdk1.8 使用的js引擎信息。
在代码中定义了默认的js引擎
ScriptEngine engine = manager.getEngineByName("javascript");
通过运行该默认的引擎报错信息可以看到,实际上用的是nashorn。

1.2 java代码中使用 nashorn

下述为简单的nashron的使用过程
demo如下:

public class FirstJavaScriptJS {
    public static void main(String args[]) throws ScriptException, IOException, NoSuchMethodException {
        ScriptEngineManager manager = new ScriptEngineManager();
        // 得到javascript脚本引擎
        ScriptEngine engine = manager.getEngineByName("javascript");
        String scriptText = "function greet(name) { println('Hello, ' + name); } ";

        try {
            System.out.println(engine.eval(scriptText));
        } catch (ScriptException e) {
            err.println(e);
        }
        //方法调用
        Invocable invocable = (Invocable) engine;
        invocable.invokeFunction("greet", "Alex");
    }
}

调试代码的路径为:

https://github.com/wangsz05/LearnDemo/tree/master/ScriptEngineDemo

参考:

1、https://blog.csdn.net/qq_48234103/article/details/123294740

标签:Java,字节,JavaScript,JS,编译,sandbox,引擎,使用
来源: https://www.cnblogs.com/TT0TT/p/16270848.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有