Commit 93a9102
authored
Update dependency rack to v3.2.6 [SECURITY] (#788)
This PR contains the following updates:
| Package | Change |
[Age](https://docs.renovatebot.com/merge-confidence/) |
[Confidence](https://docs.renovatebot.com/merge-confidence/) |
|---|---|---|---|
| [rack](https://redirect.github.com/rack/rack)
([changelog](https://redirect.github.com/rack/rack/blob/main/CHANGELOG.md))
| `3.2.5` → `3.2.6` |

|

|
### GitHub Vulnerability Alerts
####
[CVE-2026-34786](https://redirect.github.com/rack/rack/security/advisories/GHSA-q4qf-9j86-f5mh)
## Summary
`Rack::Static#applicable_rules` evaluates several `header_rules` types
against the raw URL-encoded `PATH_INFO`, while the underlying
file-serving path is decoded before the file is served. As a result, a
request for a URL-encoded variant of a static path can serve the same
file without the headers that `header_rules` were intended to apply.
In deployments that rely on `Rack::Static` to attach security-relevant
response headers to static content, this can allow an attacker to bypass
those headers by requesting an encoded form of the path.
## Details
`Rack::Static#applicable_rules` matches rule types such as `:fonts`,
`Array`, and `Regexp` directly against the incoming `PATH_INFO`. For
example:
```ruby
when :fonts
/\.(?:ttf|otf|eot|woff2|woff|svg)\z/.match?(path)
when Array
/\.(#{rule.join('|')})\z/.match?(path)
when Regexp
rule.match?(path)
```
These checks operate on the raw request path. If the request contains
encoded characters such as `%2E` in place of `.`, the rule may fail to
match even though the file path is later decoded and served successfully
by the static file server.
For example, both of the following requests may resolve to the same file
on disk:
```text
/fonts/test.woff
/fonts/test%2Ewoff
```
but only the unencoded form may receive the headers configured through
`header_rules`.
This creates a canonicalization mismatch between the path used for
header policy decisions and the path ultimately used for file serving.
## Impact
Applications that rely on `Rack::Static` `header_rules` to apply
security-relevant headers to static files may be affected.
In affected deployments, an attacker can request an encoded variant of a
static file path and receive the same file without the intended headers.
Depending on how `header_rules` are used, this may bypass protections
such as clickjacking defenses, content restrictions, or other response
policies applied to static content.
The practical impact depends on the configured rules and the types of
files being served. If `header_rules` are only used for non-security
purposes such as caching, the issue may have limited security
significance.
## Mitigation
* Update to a patched version of Rack that applies `header_rules` to a
decoded path consistently with static file resolution.
* Do not rely solely on `Rack::Static` `header_rules` for
security-critical headers where encoded path variants may reach the
application.
* Prefer setting security headers at the reverse proxy or web server
layer so they apply consistently to both encoded and unencoded path
forms.
* Normalize or reject encoded path variants for static content at the
edge, where feasible.
####
[CVE-2026-34785](https://redirect.github.com/rack/rack/security/advisories/GHSA-h2jq-g4cq-5ppq)
## Summary
`Rack::Static` determines whether a request should be served as a static
file using a simple string prefix check. When configured with URL
prefixes such as `"/css"`, it matches any request path that begins with
that string, including unrelated paths such as `"/css-config.env"` or
`"/css-backup.sql"`.
As a result, files under the static root whose names merely share the
configured prefix may be served unintentionally, leading to information
disclosure.
## Details
`Rack::Static#route_file` performs static-route matching using logic
equivalent to:
```ruby
@​urls.any? { |url| path.index(url) == 0 }
```
This checks only whether the request path starts with the configured
prefix string. It does not require a path segment boundary after the
prefix.
For example, with:
```ruby
use Rack::Static, urls: ["/css", "/js"], root: "public"
```
the following path is matched as intended:
```text
/css/style.css
```
but these paths are also matched:
```text
/css-config.env
/css-backup.sql
/csssecrets.yml
```
If such files exist under the configured static root, Rack forwards the
request to the file server and serves them as static content.
This means a configuration intended to expose only directory trees such
as `/css/...` and `/js/...` may also expose sibling files whose names
begin with those same strings.
## Impact
An attacker can request files under the configured static root whose
names share a configured URL prefix and obtain their contents.
In affected deployments, this may expose configuration files, secrets,
backups, environment files, or other unintended static content located
under the same root directory.
## Mitigation
* Update to a patched version of Rack that enforces a path boundary when
matching configured static URL prefixes.
* Match only paths that are either exactly equal to the configured
prefix or begin with `prefix + "/"`.
* Avoid placing sensitive files under the `Rack::Static` root directory.
* Prefer static URL mappings that cannot overlap with sensitive
filenames.
####
[CVE-2026-34826](https://redirect.github.com/rack/rack/security/advisories/GHSA-x8cg-fq8g-mxfx)
## Summary
`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.
This results in a denial of service condition in Rack file-serving paths
that process multipart byte range responses.
## Details
`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.
As a result, a request such as:
```http
Range: bytes=0-0,0-0,0-0,0-0,...
```
can contain thousands of overlapping one-byte ranges while still
satisfying the total-size check added for CVE-2024-26141.
When 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.
The 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.
## Impact
Applications that expose file-serving paths with byte range support may
be vulnerable to denial of service.
An 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.
## Mitigation
* Update to a patched version of Rack that limits the number of accepted
byte ranges.
* Reject or normalize multipart byte range requests containing excessive
range counts.
* Consider disabling multipart range support where it is not required.
* Apply request filtering or header restrictions at the reverse proxy or
application boundary to limit abusive `Range` headers.
####
[CVE-2026-34827](https://redirect.github.com/rack/rack/security/advisories/GHSA-v6x5-cg8r-vv6x)
## 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.
####
[CVE-2026-26961](https://redirect.github.com/rack/rack/security/advisories/GHSA-vgpv-f759-9wx3)
## 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.
####
[CVE-2026-26962](https://redirect.github.com/rack/rack/security/advisories/GHSA-rx22-g9mx-qrhv)
## 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\n 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.
####
[CVE-2026-32762](https://redirect.github.com/rack/rack/security/advisories/GHSA-qfgr-crr9-7r49)
## 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.
####
[CVE-2026-34230](https://redirect.github.com/rack/rack/security/advisories/GHSA-v569-hp3g-36wr)
## 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.
####
[CVE-2026-34763](https://redirect.github.com/rack/rack/security/advisories/GHSA-7mqq-6cf9-v2qp)
## 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.
####
[CVE-2026-34829](https://redirect.github.com/rack/rack/security/advisories/GHSA-8vqr-qjwx-82mw)
## 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.
####
[CVE-2026-34830](https://redirect.github.com/rack/rack/security/advisories/GHSA-qv7j-4883-hwh7)
## 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.
####
[CVE-2026-34831](https://redirect.github.com/rack/rack/security/advisories/GHSA-q2ww-5357-x388)
## 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 += "\n"
[
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.
####
[CVE-2026-34835](https://redirect.github.com/rack/rack/security/advisories/GHSA-g2pf-xv49-m2h5)
## 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
(?<host>
\[(?<address>#{ipv6})\]
|
(?<address>[[[:graph:]&&[^\[\]]]]*?)
)
(:(?<port>\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.
---
### Release Notes
<details>
<summary>rack/rack (rack)</summary>
###
[`v3.2.6`](https://redirect.github.com/rack/rack/blob/HEAD/CHANGELOG.md#326---2026-04-01)
[Compare
Source](https://redirect.github.com/rack/rack/compare/v3.2.5...v3.2.6)
##### Security
-
[CVE-2026-34763](https://redirect.github.com/advisories/GHSA-7mqq-6cf9-v2qp)
Root directory disclosure via unescaped regex interpolation in
`Rack::Directory`.
-
[CVE-2026-34230](https://redirect.github.com/advisories/GHSA-v569-hp3g-36wr)
Avoid O(n^2) algorithm in `Rack::Utils.select_best_encoding` which could
lead to denial of service.
-
[CVE-2026-32762](https://redirect.github.com/advisories/GHSA-qfgr-crr9-7r49)
Forwarded header semicolon injection enables Host and Scheme spoofing.
-
[CVE-2026-26961](https://redirect.github.com/advisories/GHSA-vgpv-f759-9wx3)
Raise error for multipart requests with multiple boundary parameters.
-
[CVE-2026-34786](https://redirect.github.com/advisories/GHSA-q4qf-9j86-f5mh)
`Rack::Static` `header_rules` bypass via URL-encoded path mismatch.
-
[CVE-2026-34831](https://redirect.github.com/advisories/GHSA-q2ww-5357-x388)
`Content-Length` mismatch in `Rack::Files` error responses.
-
[CVE-2026-34826](https://redirect.github.com/advisories/GHSA-x8cg-fq8g-mxfx)
Multipart byte range processing allows denial of service via excessive
overlapping ranges.
-
[CVE-2026-34835](https://redirect.github.com/advisories/GHSA-g2pf-xv49-m2h5)
`Rack::Request` accepts invalid Host characters, enabling host allowlist
bypass.
-
[CVE-2026-34830](https://redirect.github.com/advisories/GHSA-qv7j-4883-hwh7)
`Rack::Sendfile` header-based `X-Accel-Mapping` regex injection enables
unauthorized `X-Accel-Redirect`.
-
[CVE-2026-34785](https://redirect.github.com/advisories/GHSA-h2jq-g4cq-5ppq)
`Rack::Static` prefix matching can expose unintended files under the
static root.
-
[CVE-2026-34829](https://redirect.github.com/advisories/GHSA-8vqr-qjwx-82mw)
Multipart parsing without `Content-Length` header allows unbounded
chunked file uploads.
-
[CVE-2026-34827](https://redirect.github.com/advisories/GHSA-v6x5-cg8r-vv6x)
Multipart header parsing allows denial of service via escape-heavy
quoted parameters.
-
[CVE-2026-26962](https://redirect.github.com/advisories/GHSA-rx22-g9mx-qrhv)
Improper unfolding of folded multipart headers preserves CRLF in parsed
parameter values.
</details>
---
### Configuration
📅 **Schedule**: Branch creation - "" in timezone Asia/Tokyo, Automerge -
At any time (no schedule defined).
🚦 **Automerge**: Enabled.
♻ **Rebasing**: Whenever PR is behind base branch, or you tick the
rebase/retry checkbox.
🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.
---
- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box
---
This PR was generated by [Mend Renovate](https://mend.io/renovate/).
View the [repository job
log](https://developer.mend.io/github/line/line-bot-sdk-ruby).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4xMDIuMTEiLCJ1cGRhdGVkSW5WZXIiOiI0My4xMDIuMTEiLCJ0YXJnZXRCcmFuY2giOiJtYXN0ZXIiLCJsYWJlbHMiOlsiZGVwZW5kZW5jeSB1cGdyYWRlIl19-->
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>1 parent d49a4c0 commit 93a9102
1 file changed
+1
-1
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
71 | 71 | | |
72 | 72 | | |
73 | 73 | | |
74 | | - | |
| 74 | + | |
75 | 75 | | |
76 | 76 | | |
77 | 77 | | |
| |||
0 commit comments