Apr 2, 2026·6 min read·26 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.
A property shadowing vulnerability exists in protobufjs where schema-derived names can collide with and overwrite runtime-critical internal helper properties. This issue leads to uncaught runtime exceptions and crash-based Denial of Service.
An integer truncation vulnerability (CWE-197) exists in SQLite before version 3.50.2 during the processing of aggregate queries with more than 32,767 distinct column references. This causes an internal 32-bit counter to truncate to a signed 16-bit integer, producing negative values that cause out-of-bounds heap operations in release builds.
An integer overflow vulnerability in the Windows kernel-mode HTTP driver (HTTP.sys) allows an unauthenticated remote attacker to execute arbitrary code with kernel privileges or cause a Denial of Service via a specially crafted sequence of HTTP request headers.
A memory corruption vulnerability exists in the FTS5 (Full-Text Search 5) extension of SQLite prior to version 3.53.2. An attacker can construct a malicious database file containing corrupt FTS5 page data. Querying this database triggers out-of-bounds reads and heap-based buffer overflows, potentially causing a crash or arbitrary code execution.
A mass assignment vulnerability (CWE-915) in n8n's self-service settings API endpoint (PATCH /me/settings) allows authenticated Single Sign-On (SSO) users to disable SSO enforcement for their accounts by injecting administrative parameters. This bypasses organizational identity provider controls and multi-factor authentication (MFA).
CVE-2026-55699 (also identified as GHSA-4gxm-v5v7-fqc4) is a critical path traversal and arbitrary directory deletion vulnerability in the pnpm package manager. The issue exists because the manifest validation process fails to prevent relative path segments within the package 'bin' keys. When a malicious package containing structured path traversal markers is globally installed and later manipulated, pnpm resolves the target paths through path.join() and passes the resolved paths to a recursive deletion function, resulting in arbitrary directory removal.