Tag: rubygems

  • GHSA-5v64-555j-wjxm: Rack: Multipart parsing allows DoS via unbounded scan buffer growth

    • Severity: HIGH
    • CVE: CVE-2026-125111
    • Ecosystems: rubygems, rubygems, rubygems
    • Packages: rack, rack, rack

    ## Summary

    `Rack::Multipart::Parser` reads the request body in chunks of `rack.multipart.buffer_size` (1 MiB by default) into an internal scan buffer. Parsed bytes are only discarded from that buffer when a chunk ends inside a part body. A request whose parts are sized so that every chunk ends inside, or immediately after, a part’s headers is never compacted, so the buffer grows to the size of the request.

    This results in a denial of service condition through memory exhaustion for applications that parse multipart requests.

    ## Details

    The parser appends each chunk read from the input to a `StringScanner` and advances through boundaries, headers, and bodies. In the body state, when no closing boundary is found, the consumed prefix is removed before more data is read. In the header state, and in the body state when no body bytes have been consumed yet, the parser requests more data without removing anything. Bytes skipped between parts are not counted against any limit.

    An attacker can therefore construct parts that each fit within one chunk and align the chunk boundaries with the part headers. The existing limits on buffered non-file field data, header size, and preamble size do not apply, because each individual part remains small. With default limits the buffer can reach roughly 4 GiB (4096 parts of about 1 MiB). Ordinary file uploads aligned the same way are bounded by the file part limit at roughly 128 MiB per request.

    ## Impact

    Any application that parses multipart…

    Source: GitHub Security Advisories · 2026-11-10

  • GHSA-p8x9-v4hv-2w4g: Rack: Multipart boundary ambiguity guard in Rack::Multipart::Parser can be bypassed with a quoted boundary value, allowing WAF bypass

    • Severity: LOW
    • CVE: CVE-2026-125108
    • Ecosystems: rubygems, rubygems, rubygems
    • Packages: rack, rack, rack

    ## Summary

    The guard added for CVE-2026-26961 (GHSA-vgpv-f759-9wx3), which rejects multipart requests with more than one `boundary` parameter, only inspects the part of the `Content-Type` header after the boundary it extracts. A `Content-Type` whose first `boundary` parameter is empty or begins with a quote, semicolon, or comma is skipped by the extraction pattern, so a second `boundary` parameter is accepted silently and Rack parses the body with a boundary that a conforming parser would not derive from the header.

    ## Details

    `Rack::Multipart::Parser.parse_boundary` extracts the boundary with a regular expression that uses a lazy prefix and a value class excluding `”`, `;`, and `,`. For a header such as `multipart/form-data; boundary=”;boundary=AaB03x”` or `multipart/form-data; boundary=; boundary=AaB03x`, the pattern skips the first `boundary=` and anchors on the second, and the subsequent check for another `boundary=` in the remaining text finds nothing. Rack then uses `AaB03x`.

    RFC 9110 parses the first header as a single parameter whose value is `;boundary=AaB03x`, which is not a legal boundary under RFC 2046, so the only conformant outcome is rejection. Inspecting intermediaries that implement the standard grammar, such as ModSecurity, see a different boundary or no multipart body at all.

    The fix counts `boundary=` occurrences across the entire header value and rejects the request when there is more than one.

    ## Impact

    As with CVE-2026-26961, an attacker can craf…

    Source: GitHub Security Advisories · 2026-11-10

  • GHSA-2j8w-xcrc-x985: Rack: Rack::Request#host_with_port (and #base_url / #url) return the raw invalid Host header — incomplete fix of CVE-2026-34835

    • Severity: MEDIUM
    • CVE: CVE-2026-125109
    • Ecosystems: rubygems, rubygems
    • Packages: rack, rack

    ## Summary

    `Rack::Request#host_with_port`, and therefore `#base_url` and `#url`, return the raw authority string when it fails validation. An attacker-controlled `Host`, `X-Forwarded-Host`, or `Forwarded: host=` value containing characters that are not permitted in an authority is embedded verbatim in URLs generated by the application.

    This completes the fix for CVE-2026-34835 (GHSA-g2pf-xv49-m2h5), which made `#host` and `#hostname` return `nil` for an invalid authority but left this path unchanged.

    ## Details

    `Rack::Request#host_with_port` splits the authority with `split_authority`. When the `AUTHORITY` pattern does not match, no components are returned and `host_with_port` falls back to returning the unvalidated authority string. `base_url` is `”#{scheme}://#{host_with_port}”` and `url` appends the full path, so both inherit the raw value.

    For a request with `Host: evil.com/@legit.com`, `host` returns `nil` while `host_with_port` returns `evil.com/@legit.com` and `base_url` returns `http://evil.com/@legit.com`. A valid `Host` together with an invalid `X-Forwarded-Host` produces the same result, because forwarded headers take priority by default.

    ## Impact

    Applications that build absolute URLs, redirects, or origin-dependent checks from `req.url`, `req.base_url`, or `req.host_with_port`, and that do not enforce a host allowlist, may emit URLs containing attacker-chosen characters such as `@`, `/`, `?`, `#`, spaces, or angle brackets. Generated links and `Location` h…

    Source: GitHub Security Advisories · 2026-11-10

  • GHSA-wvg4-6p58-3gh3: Rack: Rack::Static header_rules bypass via dot-segment normalization mismatch

    • Severity: MEDIUM
    • CVE: CVE-2026-125110
    • Ecosystems: rubygems, rubygems, rubygems
    • Packages: rack, rack, rack

    ## Summary

    `Rack::Static` normalizes the request path with `Utils.clean_path_info` when deciding which file to serve, but matches `header_rules` against a path that is only URL-decoded. A request containing dot segments, raw or percent-encoded, is served the normalized target file while the header rules for that file’s location are not applied.

    This allows an attacker to receive a protected static file without the security headers configured for it.

    ## Details

    `Rack::Static#call` computes the served path as `Utils.clean_path_info(Utils.unescape_path(path))`. `Rack::Static#applicable_rules` applies only `Utils.unescape_path` before testing string and regular expression rules. A request for `/assets/../uploads/file.html` or `/assets/..%2fuploads/file.html` is served as `uploads/file.html`, but the decoded path `/assets/../uploads/file.html` does not start with `uploads`, so a rule scoped to that directory never matches.

    The fix for CVE-2026-34786 (GHSA-q4qf-9j86-f5mh) added URL decoding to rule matching but did not add dot segment normalization, so versions that include that fix remain affected.

    ## Impact

    Applications that use `Rack::Static` `header_rules` to attach security-relevant headers to particular paths or file types are affected. An unauthenticated attacker who knows the path of a protected file can request it through a dot segment path and receive it without those headers, for example without `Content-Disposition: attachment` or a restrictive `Content-Security-…

    Source: GitHub Security Advisories · 2026-11-10