{"id":"GHSA-x8cg-fq8g-mxfx","summary":"Rack's multipart byte range processing allows denial of service via excessive overlapping ranges","details":"## Summary\n\n`Rack::Utils.get_byte_ranges` parses the HTTP `Range` header without limiting the number of individual byte ranges. Although the existing fix for CVE-2024-26141 rejects ranges whose total byte coverage exceeds the file size, it does not restrict the count of ranges. An attacker can supply many small overlapping ranges such as `0-0,0-0,0-0,...` to trigger disproportionate CPU, memory, I/O, and bandwidth consumption per request.\n\nThis results in a denial of service condition in Rack file-serving paths that process multipart byte range responses.\n\n## Details\n\n`Rack::Utils.get_byte_ranges` accepts a comma-separated list of byte ranges and validates them based on their aggregate size, but does not impose a limit on how many individual ranges may be supplied.\n\nAs a result, a request such as:\n\n```http\nRange: bytes=0-0,0-0,0-0,0-0,...\n```\n\ncan contain thousands of overlapping one-byte ranges while still satisfying the total-size check added for CVE-2024-26141.\n\nWhen such a header is processed by Rack’s file-serving code, each range causes additional work, including multipart response generation, per-range iteration, file seek and read operations, and temporary string allocation for response size calculation and output. This allows a relatively small request header to trigger disproportionately expensive processing and a much larger multipart response.\n\nThe issue is distinct from CVE-2024-26141. That fix prevents range sets whose total byte coverage exceeds the file size, but does not prevent a large number of overlapping ranges whose summed size remains within that limit.\n\n## Impact\n\nApplications that expose file-serving paths with byte range support may be vulnerable to denial of service.\n\nAn unauthenticated attacker can send crafted `Range` headers containing many small overlapping ranges to consume excessive CPU time, memory, file I/O, and bandwidth. Repeated requests may reduce application availability and increase pressure on workers and garbage collection.\n\n## Mitigation\n\n* Update to a patched version of Rack that limits the number of accepted byte ranges.\n* Reject or normalize multipart byte range requests containing excessive range counts.\n* Consider disabling multipart range support where it is not required.\n* Apply request filtering or header restrictions at the reverse proxy or application boundary to limit abusive `Range` headers.","aliases":["CVE-2026-34826"],"modified":"2026-09-10T03:51:03.883569435Z","published":"2026-04-02T19:07:28Z","database_specific":{"cwe_ids":["CWE-400","CWE-770"],"severity":"MODERATE","github_reviewed":true,"github_reviewed_at":"2026-04-02T19:07:28Z","nvd_published_at":"2026-04-02T17:16:25Z"},"references":[{"type":"WEB","url":"https://github.com/rack/rack/security/advisories/GHSA-x8cg-fq8g-mxfx"},{"type":"ADVISORY","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-34826"},{"type":"PACKAGE","url":"https://github.com/rack/rack"},{"type":"WEB","url":"https://github.com/rubysec/ruby-advisory-db/blob/master/gems/rack/CVE-2026-34826.yml"}],"affected":[{"package":{"name":"rack","ecosystem":"RubyGems","purl":"pkg:gem/rack"},"ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"2.2.23"}]}],"versions":["0.1.0","0.2.0","0.3.0","0.4.0","0.9.0","0.9.1","1.0.0","1.0.1","1.1.0","1.1.1","1.1.1.pre","1.1.2","1.1.3","1.1.4","1.1.5","1.1.6","1.2.0","1.2.1","1.2.2","1.2.3","1.2.4","1.2.5","1.2.6","1.2.7","1.2.8","1.3.0","1.3.0.beta","1.3.0.beta2","1.3.1","1.3.10","1.3.2","1.3.3","1.3.4","1.3.5","1.3.6","1.3.7","1.3.8","1.3.9","1.4.0","1.4.1","1.4.2","1.4.3","1.4.4","1.4.5","1.4.6","1.4.7","1.5.0","1.5.0.beta.1","1.5.0.beta.2","1.5.1","1.5.2","1.5.3","1.5.4","1.5.5","1.6.0","1.6.0.beta","1.6.0.beta2","1.6.1","1.6.10","1.6.11","1.6.12","1.6.13","1.6.2","1.6.3","1.6.4","1.6.5","1.6.6","1.6.7","1.6.8","1.6.9","2.0.0.alpha","2.0.0.rc1","2.0.1","2.0.2","2.0.3","2.0.4","2.0.5","2.0.6","2.0.7","2.0.8","2.0.9","2.0.9.1","2.0.9.2","2.0.9.3","2.0.9.4","2.1.0","2.1.1","2.1.2","2.1.3","2.1.4","2.1.4.1","2.1.4.2","2.1.4.3","2.1.4.4","2.2.0","2.2.1","2.2.10","2.2.11","2.2.12","2.2.13","2.2.14","2.2.15","2.2.16","2.2.17","2.2.18","2.2.19","2.2.2","2.2.20","2.2.21","2.2.22","2.2.3","2.2.3.1","2.2.4","2.2.5","2.2.6","2.2.6.1","2.2.6.2","2.2.6.3","2.2.6.4","2.2.7","2.2.8","2.2.8.1","2.2.9"],"database_specific":{"source":"https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2026/04/GHSA-x8cg-fq8g-mxfx/GHSA-x8cg-fq8g-mxfx.json"}},{"package":{"name":"rack","ecosystem":"RubyGems","purl":"pkg:gem/rack"},"ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"3.0.0.beta1"},{"fixed":"3.1.21"}]}],"versions":["3.0.0","3.0.0.beta1","3.0.0.rc1","3.0.1","3.0.10","3.0.11","3.0.12","3.0.13","3.0.14","3.0.15","3.0.16","3.0.17","3.0.18","3.0.2","3.0.3","3.0.4","3.0.4.1","3.0.4.2","3.0.5","3.0.6","3.0.6.1","3.0.7","3.0.8","3.0.9","3.0.9.1","3.1.0","3.1.1","3.1.10","3.1.11","3.1.12","3.1.13","3.1.14","3.1.15","3.1.16","3.1.17","3.1.18","3.1.19","3.1.2","3.1.20","3.1.3","3.1.4","3.1.5","3.1.6","3.1.7","3.1.8","3.1.9"],"database_specific":{"source":"https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2026/04/GHSA-x8cg-fq8g-mxfx/GHSA-x8cg-fq8g-mxfx.json"}},{"package":{"name":"rack","ecosystem":"RubyGems","purl":"pkg:gem/rack"},"ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"3.2.0"},{"fixed":"3.2.6"}]}],"versions":["3.2.0","3.2.1","3.2.2","3.2.3","3.2.4","3.2.5"],"database_specific":{"source":"https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2026/04/GHSA-x8cg-fq8g-mxfx/GHSA-x8cg-fq8g-mxfx.json"}}],"schema_version":"1.9.0","severity":[{"type":"CVSS_V3","score":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L"}]}