SB20261105115 - Multiple vulnerabilities in Rack



SB20261105115 - Multiple vulnerabilities in Rack

Published: November 5, 2026

Security Bulletin ID SB20261105115
CSH Severity
Medium
Patch available
YES
Number of vulnerabilities 4
Exploitation vector Remote access
Highest impact Denial of service

Breakdown by Severity

Medium 75% Low 25%
  • Low
  • Medium
  • High
  • Critical

Description

This security bulletin contains information about 4 vulnerabilities.


1) Resource exhaustion (CVE-ID: N/A)

CWE-ID: CWE-400 - Resource exhaustion

CVSSv4: 8.7 [CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N]


The vulnerability allows an unauthenticated attacker to cause denial of service through memory exhaustion in applications that parse multipart requests with Rack, including in the default configuration. A single well-formed multipart request can retain memory proportional to its size for the duration of parsing, exhausting worker memory.

The vulnerability exists due to Rack::Multipart::Parser retaining already parsed data in its internal scan buffer when chunk boundaries fall inside or immediately after part headers. A remote attacker can submit a well-formed multipart body with parts sized to fit within individual chunks and aligned so that every chunk ends at these positions, preventing buffer compaction and causing the buffer to grow to the size of the request. The parser appends input chunks to a StringScanner and advances through boundaries, headers, and bodies. It removes the consumed prefix in the body state when no closing boundary is found, but requests more data without removing consumed bytes in the header state or in the body state before any body bytes have been consumed.

Chunks are controlled by rack.multipart.buffer_size, which defaults to 1 MiB. Bytes skipped between parts are not counted against any limit, and existing limits on buffered non-file field data, header size, and preamble size do not constrain this accumulation because each individual part remains small. With default limits, the scan buffer can reach roughly 4 GiB through 4096 parts of about 1 MiB each. Ordinary file uploads aligned in the same way also retain parsed data, but the file part limit bounds this case at roughly 128 MiB per request.


2) Interpretation Conflict (CVE-ID: N/A)

CWE-ID: CWE-436 - Interpretation Conflict

CVSSv4: 6.3 [CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:N/VI:L/VA:N/SC:N/SI:N/SA:N]


The vulnerability allows a remote attacker to bypass a web application firewall or other inspecting proxy in front of a Rack application by crafting a multipart request that the intermediary interprets differently from Rack. Form fields and file uploads can consequently reach the application without inspection. Rack itself grants no capability beyond that of a well-formed request with the same body.

The vulnerability exists due to incomplete duplicate-boundary detection in Rack::Multipart::Parser.parse_boundary. Its boundary-extraction regular expression uses a lazy prefix and a value class excluding quotes, semicolons, and commas. If the first boundary parameter is empty or begins with one of those characters, the pattern skips it and extracts a later boundary instead. The duplicate check examines only the text after the extracted boundary, leaving the earlier occurrence undetected. A remote attacker can send a crafted multipart request through an inspecting intermediary to a Rack application, causing Rack to accept a later boundary that differs from the intermediary's interpretation.

For example, both multipart/form-data; boundary=";boundary=AaB03x" and multipart/form-data; boundary=; boundary=AaB03x cause Rack to use AaB03x. Under RFC 9110, the quoted example instead contains a single parameter with the value ;boundary=AaB03x, which is not a legal multipart boundary under RFC 2046 and therefore requires rejection. Intermediaries implementing the standard grammar, such as ModSecurity, can see a different boundary or no multipart body at all, creating the interpretation conflict that enables the inspection bypass.


3) Improper Validation of Syntactic Correctness of Input (CVE-ID: N/A)

CWE-ID: CWE-1286 - Improper Validation of Syntactic Correctness of Input

CVSSv4: 6.3 [CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:L/VI:L/VA:N/SC:N/SI:N/SA:N]


The vulnerability allows remote attackers to inject invalid authority values into application-generated absolute URLs and redirects, bypass string-based URL or origin checks, and reflect markup when applications do not escape the value. Applications are exposed when they use Rack's req.url, req.base_url, or req.host_with_port without enforcing a host allowlist. Generated links and Location headers can be redirected through userinfo tricks.

The vulnerability exists due to Rack::Request#host_with_port falling back to the original, unvalidated authority when split_authority fails to match the AUTHORITY pattern and returns no components. A remote attacker can supply an invalid Host, or an attacker-controlled X-Forwarded-Host or Forwarded: host= value accepted by the deployment, to embed characters such as @, /, ?, #, spaces, or angle brackets verbatim in generated URLs. Forwarded headers take priority by default, so an invalid forwarded host can trigger the behavior even when Host is valid. The base_url method combines the scheme with host_with_port, and url appends the full path, propagating the invalid value through both methods.

For example, Host: evil.com/@legit.com causes host to return nil while host_with_port returns evil.com/@legit.com and base_url returns http://evil.com/@legit.com. Sinatra's redirect can emit the raw invalid authority in a Location header when a proxy forwards attacker-controlled X-Forwarded-Host. Rails overrides these methods in Action Dispatch and is not expected to be affected.


4) Incorrect Behavior Order: Validate Before Canonicalize (CVE-ID: N/A)

CWE-ID: CWE-180 - Incorrect Behavior Order: Validate Before Canonicalize

CVSSv4: 6.9 [CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:L/VA:N/SC:N/SI:N/SA:N]


The vulnerability allows an unauthenticated remote attacker to receive a static file without the security headers configured for it through Rack's Rack::Static middleware. Missing headers such as Content-Disposition: attachment or a restrictive Content-Security-Policy can allow untrusted uploaded HTML to render inline. The file contents are served unchanged.

The vulnerability exists due to inconsistent request-path canonicalization between file selection and header_rules matching. Rack::Static#call selects the file using Utils.clean_path_info(Utils.unescape_path(path)), while Rack::Static#applicable_rules only URL-decodes the path before testing string and regular expression rules, leaving dot segments unnormalized. A remote attacker can request a known protected file using raw or percent-encoded dot segments to reach the normalized target while bypassing the header rules associated with its location.

For example, requests for /assets/../uploads/file.html or /assets/..%2fuploads/file.html serve uploads/file.html, but header matching uses /assets/../uploads/file.html, which does not match a directory rule scoped to uploads. The issue affects applications that use path-specific header_rules to attach security-relevant headers to particular paths or file types; applications without path-specific header_rules are not affected.


Remediation

Install update from vendor's website.