diff --git a/gems/rack/CVE-2026-26961.yml b/gems/rack/CVE-2026-26961.yml new file mode 100644 index 0000000000..336517c961 --- /dev/null +++ b/gems/rack/CVE-2026-26961.yml @@ -0,0 +1,84 @@ +--- +gem: rack +cve: 2026-26961 +ghsa: vgpv-f759-9wx3 +url: https://github.com/rack/rack/security/advisories/GHSA-vgpv-f759-9wx3 +title: Rack's greedy multipart boundary parsing can cause parser + differentials and WAF bypass. +date: 2026-04-02 +description: | + ## Summary + + `Rack::Multipart::Parser` extracts the `boundary` parameter from + `multipart/form-data` using a greedy regular expression. When a + `Content-Type` header contains multiple `boundary` parameters, + Rack selects the last one rather than the first. + + In deployments where an upstream proxy, WAF, or intermediary + interprets the first `boundary` parameter, this mismatch can + allow an attacker to smuggle multipart content past upstream + inspection and have Rack parse a different body structure than + the intermediary validated. + + ## Details + + Rack identifies the multipart boundary using logic equivalent to: + + ```ruby + MULTIPART = %r|\Amultipart/.*boundary=\"?([^\";,]+)\"?|ni + ``` + + Because the expression is greedy, it matches the last `boundary=` + parameter in a header such as: + + ```http + Content-Type: multipart/form-data; boundary=safe; boundary=malicious + ``` + + As a result, Rack parses the request body using `malicious`, while + another component may interpret the same header using `safe`. + + This creates an interpretation conflict. If an upstream WAF or proxy + inspects multipart parts using the first boundary and Rack later + parses the body using the last boundary, a client may be able to + place malicious form fields or uploaded content in parts that Rack + accepts but the upstream component did not inspect as intended. + + This issue is most relevant in layered deployments where security + decisions are made before the request reaches Rack. + + ## Impact + + Applications that accept `multipart/form-data` uploads behind an + inspecting proxy or WAF may be affected. + + In such deployments, an attacker may be able to bypass upstream + filtering of uploaded files or form fields by sending a request + with multiple `boundary` parameters and relying on the intermediary + and Rack to parse the request differently. + + The practical impact depends on deployment architecture. If no + upstream component relies on a different multipart interpretation, + this behavior may not provide meaningful additional attacker capability. + + ## Mitigation + + * Update to a patched version of Rack that rejects ambiguous multipart + `Content-Type` headers or parses duplicate `boundary` parameters + consistently. + * Reject requests containing multiple `boundary` parameters. + * Normalize or regenerate multipart metadata at the trusted edge + before forwarding requests to Rack. + * Avoid relying on upstream inspection of malformed multipart + requests unless duplicate parameter handling is explicitly + consistent across components. +cvss_v3: 3.7 +patched_versions: + - "~> 2.2.23" + - "~> 3.1.21" + - ">= 3.2.6" +related: + url: + - https://nvd.nist.gov/vuln/detail/CVE-2026-26961 + - https://github.com/rack/rack/security/advisories/GHSA-vgpv-f759-9wx3 + - https://github.com/advisories/GHSA-vgpv-f759-9wx3 diff --git a/gems/rack/CVE-2026-26962.yml b/gems/rack/CVE-2026-26962.yml new file mode 100644 index 0000000000..35bbdb3452 --- /dev/null +++ b/gems/rack/CVE-2026-26962.yml @@ -0,0 +1,82 @@ +--- +gem: rack +cve: 2026-26962 +ghsa: rx22-g9mx-qrhv +url: https://github.com/rack/rack/security/advisories/GHSA-rx22-g9mx-qrhv +title: Rack's improper unfolding of folded multipart headers + preserves CRLF in parsed parameter values +date: 2026-04-02 +description: | + ## Summary + + `Rack::Multipart::Parser` unfolds folded multipart part headers + incorrectly. When a multipart header contains an obs-fold sequence, + Rack preserves the embedded CRLF in parsed parameter values such + as `filename` or `name` instead of removing the folded line break + during unfolding. + + As a result, applications that later reuse those parsed values in + HTTP response headers may be vulnerable to downstream header + injection or response splitting. + + ## Details + + `Rack::Multipart::Parser` accepts folded multipart header values and + unfolds them during parsing. However, the unfolding behavior does + not fully remove the embedded line break sequence from the parsed value. + + This means a multipart part header such as: + + ```http + Content-Disposition: form-data; name="file"; filename="test\r + foo.txt" + ``` + + can result in a parsed parameter value that still contains CRLF characters. + + The issue is not that Rack creates a second multipart header field. + Rather, the problem is that CRLF remains embedded in the parsed + metadata value after unfolding. If an application later uses that + value in a security-sensitive context, such as constructing an HTTP + response header, the preserved CRLF may alter downstream header parsing. + + Affected values may include multipart parameters such as + `filename`, `name`, or similar parsed header attributes. + + ## Impact + + Applications that accept multipart form uploads may be affected if + they later reuse parsed multipart metadata in HTTP headers or other + header-sensitive contexts. + + In affected deployments, an attacker may be able to supply a multipart + parameter value containing folded line breaks and cause downstream + header injection, response splitting, cache poisoning, or related + response parsing issues. + + The practical impact depends on application behavior. If parsed + multipart metadata is not reused in HTTP headers, the issue may + be limited to incorrect parsing behavior rather than a direct + exploit path. + + ## Mitigation + + * Update to a patched version of Rack that removes CRLF correctly + when unfolding folded multipart header values. + * Avoid copying upload metadata such as `filename` directly into + HTTP response headers without sanitization. + * Sanitize or reject carriage return and line feed characters in + multipart-derived values before reusing them in response headers, + logs, or downstream protocol contexts. + * Where feasible, normalize uploaded filenames before storing or + reflecting them. +cvss_v3: 4.8 +unaffected_versions: + - "< 3.2.0" +patched_versions: + - ">= 3.2.6" +related: + url: + - https://nvd.nist.gov/vuln/detail/CVE-2026-26962 + - https://github.com/rack/rack/security/advisories/GHSA-rx22-g9mx-qrhv + - https://github.com/advisories/GHSA-rx22-g9mx-qrhv diff --git a/gems/rack/CVE-2026-32762.yml b/gems/rack/CVE-2026-32762.yml new file mode 100644 index 0000000000..dc9fd5e858 --- /dev/null +++ b/gems/rack/CVE-2026-32762.yml @@ -0,0 +1,101 @@ +--- +gem: rack +cve: 2026-32762 +ghsa: qfgr-crr9-7r49 +url: https://github.com/rack/rack/security/advisories/GHSA-qfgr-crr9-7r49 +title: Rack - Forwarded Header semicolon injection enables + Host and Scheme spoofing +date: 2026-04-02 +description: | + ## Summary + + `Rack::Utils.forwarded_values` parses the RFC 7239 `Forwarded` header + by splitting on semicolons before handling quoted-string values. + Because quoted values may legally contain semicolons, a header such as: + + ```http + Forwarded: for="127.0.0.1;host=evil.com;proto=https" + ``` + + can be interpreted by Rack as multiple `Forwarded` directives rather + than as a single quoted `for` value. + + In deployments where an upstream proxy, WAF, or intermediary validates + or preserves quoted `Forwarded` values differently, this discrepancy + can allow an attacker to smuggle `host`, `proto`, `for`, or `by` + parameters through a single header value. + + ## Details + + `Rack::Utils.forwarded_values` processes the header using logic + equivalent to: + + ```ruby + forwarded_header.split(';').each_with_object({}) do |field, values| + field.split(',').each do |pair| + pair = pair.split('=').map(&:strip).join('=') + return nil unless pair =~ /\A(by|for|host|proto)="?([^"]+)"?\Z/i + (values[$1.downcase.to_sym] ||= []) << $2 + end + end + ``` + + The method splits on `;` before it parses individual `name=value` + pairs. This is inconsistent with RFC 7239, which permits quoted-string + values, and quoted strings may contain semicolons as literal content. + + As a result, a header value such as: + + ```http + Forwarded: for="127.0.0.1;host=evil.com;proto=https" + ``` + + is not treated as a single `for` value. Instead, Rack may interpret + it as if the client had supplied separate `for`, `host`, and `proto` + directives. + + This creates an interpretation conflict when another component in + front of Rack treats the quoted value as valid literal content, + while Rack reparses it as multiple forwarding parameters. + + ## Impact + + Applications that rely on `Forwarded` to derive request metadata + may observe attacker-controlled values for `host`, `proto`, `for`, + or related URL components. + + In affected deployments, this can lead to host or scheme spoofing + in derived values such as `req.host`, `req.scheme`, `req.base_url`, + or `req.url`. Applications that use those values for password reset + links, redirects, absolute URL generation, logging, IP-based + decisions, or backend requests may be vulnerable to downstream + security impact. + + The practical security impact depends on deployment architecture. + If clients can already supply arbitrary trusted `Forwarded` + parameters directly, this bug may not add meaningful attacker + capability. The issue is most relevant where an upstream component + and Rack interpret the same `Forwarded` header differently. + + ## Mitigation + + * Update to a patched version of Rack that parses `Forwarded` + quoted-string values before splitting on parameter delimiters. + * Avoid trusting client-supplied `Forwarded` headers unless they + are normalized or regenerated by a trusted reverse proxy. + * Prefer stripping inbound `Forwarded` headers at the edge and + reconstructing them from trusted proxy metadata. + * Avoid using `req.host`, `req.scheme`, `req.base_url`, or + `req.url` for security-sensitive operations unless the forwarding + chain is explicitly trusted and validated. +cvss_v3: 4.8 +unaffected_versions: + - "< 3.0.0.beta1" +patched_versions: + - "~> 3.1.21" + - ">= 3.2.6" +related: + url: + - https://nvd.nist.gov/vuln/detail/CVE-2026-32762 + - https://github.com/rack/rack/security/advisories/GHSA-qfgr-crr9-7r49 + - https://github.com/advisories/GHSA-qfgr-crr9-7r49 diff --git a/gems/rack/CVE-2026-34230.yml b/gems/rack/CVE-2026-34230.yml new file mode 100644 index 0000000000..e7ac0fd161 --- /dev/null +++ b/gems/rack/CVE-2026-34230.yml @@ -0,0 +1,99 @@ +--- +gem: rack +cve: 2026-34230 +ghsa: v569-hp3g-36wr +url: https://github.com/rack/rack/security/advisories/GHSA-v569-hp3g-36wr +title: Rack has quadratic complexity in Rack::Utils.select_best_encoding + via wildcard Accept-Encoding header +date: 2026-04-02 +description: | + ## Summary + + `Rack::Utils.select_best_encoding` processes `Accept-Encoding` values + with quadratic time complexity when the header contains many + wildcard (`*`) entries. Because this method is used by `Rack::Deflater` + to choose a response encoding, an unauthenticated attacker can send + a single request with a crafted `Accept-Encoding` header and cause + disproportionate CPU consumption on the compression middleware path. + + This results in a denial of service condition for applications + using `Rack::Deflater`. + + ## Details + + `Rack::Utils.select_best_encoding` expands parsed `Accept-Encoding` + values into a list of candidate encodings. When an entry is `*`, + the method computes the set of concrete encodings by subtracting + the encodings already present in the request: + + ```ruby + if m == "*" + (available_encodings - accept_encoding.map(&:first)).each do |m2| + expanded_accept_encoding << [m2, q, preference] + end + else + expanded_accept_encoding << [m, q, preference] + end + ``` + + Because `accept_encoding.map(&:first)` is evaluated inside the loop, + it is recomputed for each wildcard entry. If the request contains + `N` wildcard entries, this produces repeated scans over the full + parsed header and causes quadratic behavior. + + After expansion, the method also performs additional work over + `expanded_accept_encoding`, including per-entry deletion, which + further increases the cost for large inputs. + + `Rack::Deflater` invokes this method for each request when the + middleware is enabled: + + ```ruby + Utils.select_best_encoding(ENCODINGS, Utils.parse_encodings(accept_encoding)) + ``` + + As a result, a client can trigger this expensive code path simply + by sending a large `Accept-Encoding` header containing many + repeated wildcard values. + + For example, a request with an approximately 8 KB `Accept-Encoding` + header containing about 1,000 `*;q=0.5` entries can cause roughly + 170 ms of CPU time in a single request on the `Rack::Deflater` + path, compared to a negligible baseline for a normal header. + + This issue is distinct from CVE-2024-26146. That issue concerned + regular expression denial of service during `Accept` header parsing, + whereas this issue arises later during encoding selection after + the header has already been parsed. + + ## Impact + + Any Rack application using `Rack::Deflater` may be affected. + + An unauthenticated attacker can send requests with crafted + `Accept-Encoding` headers to trigger excessive CPU usage in the + encoding selection logic. Repeated requests can consume worker + time disproportionately and reduce application availability. + + The attack does not require invalid HTTP syntax or large payload + bodies. A single header-sized request is sufficient to reach the + vulnerable code path. + + ## Mitigation + + * Update to a patched version of Rack in which encoding selection + does not repeatedly rescan the parsed header for wildcard entries. + * Avoid enabling `Rack::Deflater` on untrusted traffic. + * Apply request filtering or header size / format restrictions + at the reverse proxy or application boundary to limit abusive + `Accept-Encoding` values. +cvss_v3: 5.3 +patched_versions: + - "~> 2.2.23" + - "~> 3.1.21" + - ">= 3.2.6" +related: + url: + - https://nvd.nist.gov/vuln/detail/CVE-2026-34230 + - https://github.com/rack/rack/security/advisories/GHSA-v569-hp3g-36wr + - https://github.com/advisories/GHSA-v569-hp3g-36wr diff --git a/gems/rack/CVE-2026-34763.yml b/gems/rack/CVE-2026-34763.yml new file mode 100644 index 0000000000..a6cf97e5b4 --- /dev/null +++ b/gems/rack/CVE-2026-34763.yml @@ -0,0 +1,63 @@ +--- +gem: rack +cve: 2026-34763 +ghsa: 7mqq-6cf9-v2qp +url: https://github.com/rack/rack/security/advisories/GHSA-7mqq-6cf9-v2qp +title: Rack has a root directory disclosure via unescaped regex + interpolation in Rack::Directory +date: 2026-04-02 +description: | + ## Summary + + `Rack::Directory` interpolates the configured `root` path directly + into a regular expression when deriving the displayed directory path. + If `root` contains regex metacharacters such as `+`, `*`, or `.`, + the prefix stripping can fail and the generated directory listing + may expose the full filesystem path in the HTML output. + + ## Details + + `Rack::Directory::DirectoryBody#each` computes the visible path + using code equivalent to: + + ```ruby + show_path = Utils.escape_html(path.sub(/\A#{root}/, '')) + ``` + + Here, `root` is a developer-configured filesystem path. It is + normalized earlier with `File.expand_path(root)` and then inserted + directly into a regular expression without escaping. + + Because the value is treated as regex syntax rather than as a + literal string, metacharacters in the configured path can change + how the prefix match behaves. When that happens, the expected root + prefix is not removed from `path`, and the absolute filesystem path + is rendered into the HTML directory listing. + + ## Impact + + If `Rack::Directory` is configured to serve a directory whose + absolute path contains regex metacharacters, the generated directory + listing may disclose the full server filesystem path instead of + only the request-relative path. + + This can expose internal deployment details such as directory + layout, usernames, mount points, or naming conventions that would + otherwise not be visible to clients. + + ## Mitigation + + * Update to a patched version of Rack in which the root prefix + is removed using an escaped regular expression. + * Avoid using `Rack::Directory` with a root path that contains + regular expression metacharacters. +cvss_v3: 5.3 +patched_versions: + - "~> 2.2.23" + - "~> 3.1.21" + - ">= 3.2.6" +related: + url: + - https://nvd.nist.gov/vuln/detail/CVE-2026-34763 + - https://github.com/rack/rack/security/advisories/GHSA-7mqq-6cf9-v2qp + - https://github.com/advisories/GHSA-7mqq-6cf9-v2qp diff --git a/gems/rack/CVE-2026-34827.yml b/gems/rack/CVE-2026-34827.yml new file mode 100644 index 0000000000..1c1dd0dacf --- /dev/null +++ b/gems/rack/CVE-2026-34827.yml @@ -0,0 +1,73 @@ +--- +gem: rack +cve: 2026-34827 +ghsa: v6x5-cg8r-vv6x +url: https://github.com/rack/rack/security/advisories/GHSA-v6x5-cg8r-vv6x +title: Rack's multipart header parsing allows Denial of Service via + escape-heavy quoted parameters +date: 2026-04-02 +description: | + ## Summary + + `Rack::Multipart::Parser#handle_mime_head` parses quoted multipart + parameters such as `Content-Disposition: form-data; name="..."` + using repeated `String#index` searches combined with `String#slice!` + prefix deletion. For escape-heavy quoted values, this causes + super-linear processing. + + An unauthenticated attacker can send a crafted `multipart/form-data` + request containing many parts with long backslash-escaped parameter + values to trigger excessive CPU usage during multipart parsing. + + This results in a denial of service condition in Rack applications + that accept multipart form data. + + ## Details + + `Rack::Multipart::Parser#handle_mime_head` parses quoted parameter + values by repeatedly: + + 1. Searching for the next quote or backslash, + 2. Copying the preceding substring into a new buffer, and + 3. Removing the processed prefix from the original string with `slice!`. + + An attacker can exploit this by sending a multipart request with many + parts whose `name` parameters contain long escape-heavy values such as: + + ```text + name="a\\a\\a\\a\\a\\..." + ``` + + Under default Rack limits, a request can contain up to 4095 parts. If + many of those parts use long quoted values with dense escape characters, + the parser performs disproportionately expensive CPU work while + remaining within normal request size and part-count limits. + + ## Impact + + Any Rack application that accepts `multipart/form-data` requests may be + affected, including file upload endpoints and standard HTML form handlers. + + An unauthenticated attacker can send crafted multipart requests that + consume excessive CPU time during request parsing. Repeated requests + can tie up application workers, reduce throughput, and degrade or + deny service availability. + + ## Mitigation + + * Update to a patched version of Rack that parses quoted multipart + parameters without repeated rescanning and destructive prefix deletion. + * Apply request throttling or rate limiting to multipart upload endpoints. + * Where operationally feasible, restrict or isolate multipart parsing + on untrusted high-volume endpoints. +cvss_v3: 7.5 +unaffected_versions: + - "< 3.0.0.beta1" +patched_versions: + - "~> 3.1.21" + - ">= 3.2.6" +related: + url: + - https://nvd.nist.gov/vuln/detail/CVE-2026-34827 + - https://github.com/rack/rack/security/advisories/GHSA-v6x5-cg8r-vv6x + - https://github.com/advisories/GHSA-v6x5-cg8r-vv6x diff --git a/gems/rack/CVE-2026-34829.yml b/gems/rack/CVE-2026-34829.yml new file mode 100644 index 0000000000..2944793040 --- /dev/null +++ b/gems/rack/CVE-2026-34829.yml @@ -0,0 +1,81 @@ +--- +gem: rack +cve: 2026-34829 +ghsa: 8vqr-qjwx-82mw +url: https://github.com/rack/rack/security/advisories/GHSA-8vqr-qjwx-82mw +title: Rack's multipart parsing without Content-Length header allows + unbounded chunked file uploads +date: 2026-04-02 +description: | + ## Summary + + `Rack::Multipart::Parser` only wraps the request body in a `BoundedIO` + when `CONTENT_LENGTH` is present. When a `multipart/form-data` request + is sent without a `Content-Length` header, such as with HTTP chunked + transfer encoding, multipart parsing continues until end-of-stream + with no total size limit. + + For file parts, the uploaded body is written directly to a temporary + file on disk rather than being constrained by the buffered in-memory + upload limit. An unauthenticated attacker can therefore stream an + arbitrarily large multipart file upload and consume unbounded disk space. + + This results in a denial of service condition for Rack applications + that accept multipart form data. + + ## Details + + `Rack::Multipart::Parser.parse` applies `BoundedIO` only when + `content_length` is not `nil`: + + ```ruby + io = BoundedIO.new(io, content_length) if content_length + ``` + + When `CONTENT_LENGTH` is absent, the parser reads the multipart body + until EOF without a global byte limit. + + Although Rack enforces `BUFFERED_UPLOAD_BYTESIZE_LIMIT` for retained + non-file parts, file uploads are handled differently. When a multipart + part includes a filename, the body is streamed to a `Tempfile`, and + the retained-size accounting is not applied to that file content. + As a result, file parts are not subject to the same upload size bound. + + An attacker can exploit this by sending a chunked `multipart/form-data` + request containing a file part and continuously streaming data without + declaring a `Content-Length`. Rack will continue writing the uploaded + data to disk until the client stops or the server exhausts available storage. + + ## Impact + + Any Rack application that accepts `multipart/form-data` uploads may be + affected if no upstream component enforces a request body size limit. + + An unauthenticated attacker can send a large chunked file upload to + consume disk space on the application host. This may cause request + failures, application instability, or broader service disruption if + the host runs out of available storage. + + The practical impact depends on deployment architecture. Reverse proxies + or application servers that enforce upload limits may reduce or eliminate + exploitability, but Rack itself does not impose a total multipart + upload limit in this code path when `CONTENT_LENGTH` is absent. + + ## Mitigation + + * Update to a patched version of Rack that enforces a total multipart + upload size limit even when `CONTENT_LENGTH` is absent. + * Enforce request body size limits at the reverse proxy or + application server. + * Isolate temporary upload storage and monitor disk consumption + for multipart endpoints. +cvss_v3: 7.5 +patched_versions: + - "~> 2.2.23" + - "~> 3.1.21" + - ">= 3.2.6" +related: + url: + - https://nvd.nist.gov/vuln/detail/CVE-2026-34829 + - https://github.com/rack/rack/security/advisories/GHSA-8vqr-qjwx-82mw + - https://github.com/advisories/GHSA-8vqr-qjwx-82mw diff --git a/gems/rack/CVE-2026-34830.yml b/gems/rack/CVE-2026-34830.yml new file mode 100644 index 0000000000..651e1fc317 --- /dev/null +++ b/gems/rack/CVE-2026-34830.yml @@ -0,0 +1,99 @@ +--- +gem: rack +cve: 2026-34830 +ghsa: qv7j-4883-hwh7 +url: https://github.com/rack/rack/security/advisories/GHSA-qv7j-4883-hwh7 +title: Rack::Sendfile header-based X-Accel-Mapping regex injection + enables unauthorized X-Accel-Redirect +date: 2026-04-02 +description: | + ## Summary + + `Rack::Sendfile#map_accel_path` interpolates the value of the + `X-Accel-Mapping` request header directly into a regular expression + when rewriting file paths for `X-Accel-Redirect`. Because the header + value is not escaped, an attacker who can supply `X-Accel-Mapping` + to the backend can inject regex metacharacters and control the + generated `X-Accel-Redirect` response header. + + In deployments using `Rack::Sendfile` with `x-accel-redirect`, this + can allow an attacker to cause nginx to serve unintended files + from configured internal locations. + + ## Details + + `Rack::Sendfile#map_accel_path` processes header-supplied mappings + using logic equivalent to: + + ```ruby + mapping.split(',').map(&:strip).each do |m| + internal, external = m.split('=', 2).map(&:strip) + new_path = path.sub(/\A#{internal}/i, external) + return new_path unless path == new_path + end + ``` + + Here, `internal` comes from the `HTTP_X_ACCEL_MAPPING` request header + and is inserted directly into a regular expression without escaping. + This gives the header value regex semantics rather than treating + it as a literal prefix. + + As a result, an attacker can supply metacharacters such as `.*` + or capture groups to alter how the path substitution is performed. + For example, a mapping such as: + + ```http + X-Accel-Mapping: .*=/protected/secret.txt + ``` + + causes the entire source path to match and rewrites the redirect + target to a clean attacker-chosen internal path. + + This differs from the documented behavior of the header-based + mapping path, which is described as a simple substitution. While + application-supplied mappings may intentionally support regular + expressions, header-supplied mappings should be treated as + literal path prefixes. + + The issue is only exploitable when untrusted `X-Accel-Mapping` + headers can reach Rack. One realistic case is a reverse proxy + configuration that intends to set `X-Accel-Mapping` itself, but + fails to do so on some routes, allowing a client-supplied header + to pass through unchanged. + + ## Impact + + Applications using `Rack::Sendfile` with `x-accel-redirect` may + be affected if the backend accepts attacker-controlled + `X-Accel-Mapping` headers. + + In affected deployments, an attacker may be able to control the + `X-Accel-Redirect` response header and cause nginx to serve files + from internal locations that were not intended to be reachable + through the application. This can lead to unauthorized file disclosure. + + The practical impact depends on deployment architecture. If the + proxy always strips or overwrites `X-Accel-Mapping`, or if the + application uses explicit configured mappings instead of the + request header, exploitability may be eliminated. + + ## Mitigation + + * Update to a patched version of Rack that treats header-supplied + `X-Accel-Mapping` values as literal strings rather than regular expressions. + * Strip or overwrite inbound `X-Accel-Mapping` headers at the + reverse proxy so client-supplied values never reach Rack. + * Prefer explicit application-configured sendfile mappings + instead of relying on request-header mappings. + * Review proxy sub-locations and inherited header settings to + ensure `X-Accel-Mapping` is consistently set on all backend routes. +cvss_v3: 5.9 +patched_versions: + - "~> 2.2.23" + - "~> 3.1.21" + - ">= 3.2.6" +related: + url: + - https://nvd.nist.gov/vuln/detail/CVE-2026-34830 + - https://github.com/rack/rack/security/advisories/GHSA-qv7j-4883-hwh7 + - https://github.com/advisories/GHSA-qv7j-4883-hwh7 diff --git a/gems/rack/CVE-2026-34831.yml b/gems/rack/CVE-2026-34831.yml new file mode 100644 index 0000000000..2986fbe30c --- /dev/null +++ b/gems/rack/CVE-2026-34831.yml @@ -0,0 +1,94 @@ +--- +gem: rack +cve: 2026-34831 +ghsa: q2ww-5357-x388 +url: https://github.com/rack/rack/security/advisories/GHSA-q2ww-5357-x388 +title: Rack has Content-Length mismatch in Rack::Files error responses +date: 2026-04-02 +description: | + ## Summary + + `Rack::Files#fail` sets the `Content-Length` response header using + `String#size` instead of `String#bytesize`. When the response body + contains multibyte UTF-8 characters, the declared `Content-Length` + is smaller than the number of bytes actually sent on the wire. + + Because `Rack::Files` reflects the requested path in 404 responses, + an attacker can trigger this mismatch by requesting a non-existent + path containing percent-encoded UTF-8 characters. + + This results in incorrect HTTP response framing and may cause + response desynchronization in deployments that rely on the + incorrect `Content-Length` value. + + ## Details + + `Rack::Files#fail` constructs error responses using logic equivalent to: + + ```ruby + def fail(status, body, headers = {}) + body += " + " + [ + status, + { + "content-type" => "text/plain", + "content-length" => body.size.to_s, + "x-cascade" => "pass" + }.merge!(headers), + [body] + ] + end + ``` + + Here, `body.size` returns the number of characters, not the number + of bytes. For multibyte UTF-8 strings, this produces an incorrect + `Content-Length` value. + + `Rack::Files` includes the decoded request path in 404 responses. + A request containing percent-encoded UTF-8 path components therefore + causes the response body to contain multibyte characters, while + the `Content-Length` header still reflects character count rather + than byte count. + + As a result, the server can send more bytes than declared in + the response headers. + + This violates HTTP message framing requirements, which define + `Content-Length` as the number of octets in the message body. + + ## Impact + + Applications using `Rack::Files` may emit incorrectly framed error + responses when handling requests for non-existent paths containing + multibyte characters. + + In some deployment topologies, particularly with keep-alive connections + and intermediaries that rely on `Content-Length`, this mismatch + may lead to response parsing inconsistencies or response + desynchronization. The practical exploitability depends on the + behavior of downstream proxies, clients, and connection reuse. + + Even where no secondary exploitation is possible, the response is + malformed and may trigger protocol errors in strict components. + + ## Mitigation + + * Update to a patched version of Rack that computes `Content-Length` + using `String#bytesize`. + * Avoid exposing `Rack::Files` directly to untrusted traffic until + a fix is available, if operationally feasible. + * Where possible, place Rack behind a proxy or server that normalizes + or rejects malformed backend responses. + * Prefer closing backend connections on error paths if response + framing anomalies are a concern. +cvss_v3: 4.8 +patched_versions: + - "~> 2.2.23" + - "~> 3.1.21" + - ">= 3.2.6" +related: + url: + - https://nvd.nist.gov/vuln/detail/CVE-2026-34831 + - https://github.com/rack/rack/security/advisories/GHSA-q2ww-5357-x388 + - https://github.com/advisories/GHSA-q2ww-5357-x388 diff --git a/gems/rack/CVE-2026-34835.yml b/gems/rack/CVE-2026-34835.yml new file mode 100644 index 0000000000..89350cc3f1 --- /dev/null +++ b/gems/rack/CVE-2026-34835.yml @@ -0,0 +1,123 @@ +--- +gem: rack +cve: 2026-34835 +ghsa: g2pf-xv49-m2h5 +url: https://github.com/rack/rack/security/advisories/GHSA-g2pf-xv49-m2h5 +title: Rack::Request accepts invalid Host characters, enabling + host allowlist bypass +date: 2026-04-02 +description: | + ## Summary + + `Rack::Request` parses the `Host` header using an `AUTHORITY` regular + expression that accepts characters not permitted in RFC-compliant + hostnames, including `/`, `?`, `#`, and `@`. Because `req.host` + returns the full parsed value, applications that validate hosts + using naive prefix or suffix checks can be bypassed. + + For example, a check such as `req.host.start_with?("myapp.com")` can + be bypassed with `Host: myapp.com@evil.com`, and a check such as + `req.host.end_with?("myapp.com")` can be bypassed with + `Host: evil.com/myapp.com`. + + This can lead to host header poisoning in applications that use + `req.host`, `req.url`, or `req.base_url` for link generation, + redirects, or origin validation. + + ## Details + + `Rack::Request` parses the authority component using logic equivalent to: + + ```ruby + AUTHORITY = / + \A + (? + \[(?
#{ipv6})\] + | + (?
[[[:graph:]&&[^\[\]]]]*?) + ) + (:(?\d+))? + \z + /x + ``` + + The character class used for non-IPv6 hosts accepts nearly all + printable characters except `[` and `]`. This includes reserved + URI delimiters such as `@`, `/`, `?`, and `#`, which are not + valid hostname characters under RFC 3986 host syntax. + + As a result, values such as the following are accepted and returned + through `req.host`: + + ```text + myapp.com@evil.com + evil.com/myapp.com + evil.com#myapp.com + ``` + + Applications that attempt to allowlist hosts using string prefix or + suffix checks may therefore treat attacker-controlled hosts as + trusted. For example: + + ```ruby + req.host.start_with?("myapp.com") + ``` + + accepts: + + ```text + myapp.com@evil.com + ``` + + and: + + ```ruby + req.host.end_with?("myapp.com") + ``` + + accepts: + + ```text + evil.com/myapp.com + ``` + + When those values are later used to build absolute URLs or enforce + origin restrictions, the application may produce attacker-controlled + results. + + ## Impact + + Applications that rely on `req.host`, `req.url`, or `req.base_url` + may be affected if they perform naive host validation or assume + Rack only returns RFC-valid hostnames. + + In affected deployments, an attacker may be able to bypass host + allowlists and poison generated links, redirects, or origin-dependent + security decisions. This can enable attacks such as password reset + link poisoning or other host header injection issues. + + The practical impact depends on application behavior. If the + application or reverse proxy already enforces strict host validation, + exploitability may be reduced or eliminated. + + ## Mitigation + + * Update to a patched version of Rack that rejects invalid + authority characters in `Host`. + * Enforce strict `Host` header validation at the reverse proxy + or load balancer. + * Do not rely on prefix or suffix string checks such as + `start_with?` or `end_with?` for host allowlisting. + * Use exact host allowlists, or exact subdomain boundary checks, + after validating that the host is syntactically valid. +cvss_v3: 4.8 +unaffected_versions: + - "< 3.0.0.beta1" +patched_versions: + - "~> 3.1.21" + - ">= 3.2.6" +related: + url: + - https://nvd.nist.gov/vuln/detail/CVE-2026-34835 + - https://github.com/rack/rack/security/advisories/GHSA-g2pf-xv49-m2h5 + - https://github.com/advisories/GHSA-g2pf-xv49-m2h5