Apr 2, 2026·6 min read·4 visits
Unbounded parsing of HTTP Range headers in Rack allows remote, unauthenticated attackers to cause a denial-of-service condition. By sending thousands of range segments in a single request, attackers exhaust server CPU, memory, and I/O resources during multipart MIME generation.
CVE-2026-34826 is an uncontrolled resource consumption vulnerability in Rack's HTTP Range header parser, specifically within `Rack::Utils.get_byte_ranges`. By failing to limit the number of byte ranges processed in a single request, an unauthenticated attacker can induce a denial-of-service condition through CPU, memory, and I/O exhaustion. This issue affects multiple versions of the Rack web server interface and is fully patched in versions 2.2.23, 3.1.21, and 3.2.6.
Rack serves as the foundational interface for Ruby web applications, bridging requests between web servers and web frameworks. One of its built-in features is supporting partial content delivery via the HTTP Range header. This header allows clients to request specific byte ranges of a resource, enabling resumable downloads and parallel fetching.
The vulnerability, identified as CVE-2026-34826, resides within the HTTP Range header parsing logic implemented in Rack::Utils.get_byte_ranges. The parser correctly processes valid range requests but fails to enforce an upper bound on the number of discrete ranges an application will process in a single request. This omission introduces an uncontrolled resource consumption vulnerability (CWE-400).
When exposed to an HTTP request containing a large number of range specifications, the server attempts to parse, extract, and construct a multipart response for every requested segment. This triggers severe CPU, memory, and I/O pressure, rendering the application unavailable to legitimate users.
The root cause of this vulnerability is an algorithmic complexity flaw combined with unbounded resource allocation (CWE-770). The Rack::Utils.get_byte_ranges function iterates over every range segment defined in the Range header using a regular expression split. The logic scales linearly $O(N)$ with the number of segments requested, where $N$ is completely controlled by the client.
A previous patch for CVE-2024-26141 attempted to secure this subsystem by limiting the total cumulative byte coverage, preventing attackers from requesting overlapping ranges that expand to exhaustive memory allocations. However, that patch did not restrict the sheer count of discrete ranges. The system still attempts to process each requested segment sequentially, regardless of how small it is.
For each parsed segment, the server performs specific operations: computing offsets, seeking the file pointer, reading data into memory, and constructing a unique multipart MIME segment. Each MIME segment requires generating boundary strings and calculating Content-Type and Content-Range headers. When $N$ reaches the thousands, the overhead of these operations causes the application thread to block synchronously.
The pre-patch implementation of get_byte_ranges captures the raw string from the Range: bytes=... header and immediately splits it into an array using the regular expression /,[ \t]*/. The application then iterates over the resulting array. No validation is performed on the array size or the number of delimiters before this operation begins.
The patch introduced by Jeremy Evans in commit 9138756fb0bcfb500abbb0b8ed90bc24911ff6a3 mitigates this flaw by implementing a strict upper bound on the number of processed ranges. The developers added a max_ranges keyword argument with a default value of 100. This configuration limits the attack surface while remaining highly permissive for legitimate partial content requests.
To enforce this limit efficiently, the patched code evaluates the raw string before applying the regular expression. By invoking byte_range.count(','), the function determines the number of range segments in $O(1)$ time relative to the parsing loop. If the comma count meets or exceeds max_ranges, the function immediately returns nil, terminating processing and ignoring the malicious header entirely.
- def get_byte_ranges(http_range, size)
+ def get_byte_ranges(http_range, size, max_ranges: 100)
return nil if size.zero?
return nil unless http_range && http_range =~ /bytes=([^;]+)/
+ byte_range = $1
+ return nil if byte_range.count(',') >= max_ranges
ranges = []
- $1.split(/,[ \t]*/).each do |range_spec|
+ byte_range.split(/,[ \t]*/).each do |range_spec|Exploitation of this vulnerability requires no specialized tools, authentication, or complex network positioning. The attacker only needs the ability to route standard HTTP GET requests to a static file served by the vulnerable Rack implementation. The target file must be large enough to be eligible for range requests, but the actual content is irrelevant to the attack.
The attacker constructs a malicious request by injecting an excessive number of identical or overlapping, small ranges into the HTTP Range header. A typical payload consists of thousands of repetitions of the string 0-0 separated by commas. This forces the server to repeatedly request the first byte of the file.
The following proof-of-concept command demonstrates the simplicity of the attack vector. It utilizes standard Unix utilities to generate an HTTP request containing 5,000 discrete range queries. Upon receiving this payload, the vulnerable Ruby process will spike in CPU utilization and hold the connection open while struggling to formulate the extensive multipart response.
# PoC command to trigger the vulnerability
curl -H "Range: bytes=$(python3 -c "print(','.join(['0-0']*5000))")" http://target-app.com/static/image.pngThe primary impact of CVE-2026-34826 is a denial-of-service condition affecting the availability of the web application. While the CVSS v3.1 score is calculated as 5.3 (Medium), a sustained attack can effectively render the application unresponsive. The vulnerability is classified under MITRE ATT&CK technique T1499.004, Endpoint Denial of Service: Application Exhaustion Flood.
The attack causes three distinct types of resource exhaustion on the underlying system. First, the regex engine consumes significant CPU cycles processing the large string split. Second, repeated read requests force I/O thrashing, heavily utilizing the disk controller. Third, the dynamic string allocation required to build thousands of multipart MIME headers drives up memory consumption, triggering the Ruby garbage collector and causing further performance degradation.
Because the attack exploits the synchronous processing model of typical Rack implementations, a relatively low volume of concurrent malicious requests can exhaust the available worker pool. Once all worker threads are occupied attempting to process the unbounded range payloads, subsequent requests from legitimate users will queue and eventually time out.
The definitive remediation for CVE-2026-34826 is updating the Rack gem to a patched version. The maintainers have released security updates across multiple supported branches. Organizations must upgrade to Rack versions 2.2.23, 3.1.21, or 3.2.6 depending on their current deployment branch.
If immediate patching is not viable, security engineering teams can implement mitigation strategies at the network edge. Web Application Firewalls (WAF), load balancers, or reverse proxies can be configured to inspect the HTTP Range header. A rule should be deployed to reject requests where the Range header contains an abnormally high number of comma characters (for example, exceeding 50).
Organizations should also leverage log analysis platforms to detect exploitation attempts. Security operators should monitor access logs for HTTP 206 Partial Content responses associated with unusually high latency or payloads containing abnormally long Range header strings. Detecting these indicators will help identify active reconnaissance or ongoing denial-of-service campaigns.
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L| Product | Affected Versions | Fixed Version |
|---|---|---|
Rack Rack Core Team | < 2.2.23 | 2.2.23 |
Rack Rack Core Team | >= 3.0.0.beta1, < 3.1.21 | 3.1.21 |
Rack Rack Core Team | >= 3.2.0, < 3.2.6 | 3.2.6 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-400, CWE-770 |
| Attack Vector | Network |
| CVSS Score | 5.3 |
| Impact | Partial Availability |
| Exploit Status | Proof of Concept |
| KEV Status | Not Listed |
The software does not properly control the allocation and maintenance of a limited resource thereby enabling an actor to influence the amount of resources consumed, eventually leading to the exhaustion of available resources.