geotools没有过滤jxpath表达式导致存在RCE的方法:
org.geotools.data.complex.expression.FeaturePropertyAccessorFactory.FeaturePropertyAccessor.get
public <T> T get(Object object, String xpath, Class<T> target) throws IllegalArgumentException {
// 创建一个新的JXPathContext对象,用于解析传入的object
JXPathContext context = JXPathContext.newContext(object);
// 获取所有已声明的命名空间前缀
Enumeration declaredPrefixes = this.namespaces.getDeclaredPrefixes();
// 遍历所有命名空间前缀,并将它们注册到context中
while(declaredPrefixes.hasMoreElements()) {
String prefix = (String)declaredPrefixes.nextElement();
String uri = this.namespaces.getURI(prefix);
context.registerNamespace(prefix, uri);
}
// 使用context对象迭代匹配xpath表达式的所有指针
Iterator it = context.iteratePointers(xpath);
// 存储匹配结果的列表
List results = new ArrayList();
// 遍历所有匹配的指针
while(it.hasNext()) {
Pointer pointer = (Pointer)it.next();
// 如果指针是AttributeNodePointer类型,获取它的立即属性
if (pointer instanceof AttributeNodePointer) {
results.add(((AttributeNodePointer)pointer).getImmediateAttribute());
} else {
// 否则获取指针的值
results.add(pointer.getValue());
}
}
// 如果结果列表为空,抛出异常
if (results.isEmpty()) {
throw new IllegalArgumentException("x-path gives no results.");
} else if (results.size() == 1) {
// 如果只有一个结果,返回该结果
return results.get(0);
} else {
// 如果有多个结果,返回结果列表
return results;
}
}
这段Java代码定义了一个泛型方法 get
,用于通过XPath从给定对象中提取数据。主要功能是接受一个对象和一个XPath表达式,从对象中提取数据并返回。如果结果为空,则抛出异常;如果结果有一个,则返回单个结果;如果结果有多个,则返回结果列表。
通过XPath从给定对象中提取数据的代码是:
// xpath传入恶意命令,执行完这句代码命令执行
Iterator it = context.iteratePointers(xpath);
jxpath RCE漏洞原理,可以参考浅析Apache Commons Jxpath命令执行分析(CVE-2022-41852) - 跳跳糖 (tttang.com)