Skip to content

Commit c9f8613

Browse files
committed
GHSA/SYNC: 3 (of the 13) brand new rack advisories
1 parent b1e3c15 commit c9f8613

File tree

3 files changed

+255
-0
lines changed

3 files changed

+255
-0
lines changed

gems/rack/CVE-2026-34785.yml

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
---
2+
gem: rack
3+
cve: 2026-34785
4+
ghsa: h2jq-g4cq-5ppq
5+
url: https://github.com/rack/rack/security/advisories/GHSA-h2jq-g4cq-5ppq
6+
title: Rack::Static prefix matching can expose unintended files under
7+
the static root
8+
date: 2026-04-02
9+
description: |
10+
## Summary
11+
12+
`Rack::Static` determines whether a request should be served as a
13+
static file using a simple string prefix check. When configured
14+
with URL prefixes such as `"/css"`, it matches any request path
15+
that begins with that string, including unrelated paths such as
16+
`"/css-config.env"` or `"/css-backup.sql"`.
17+
18+
As a result, files under the static root whose names merely share
19+
the configured prefix may be served unintentionally, leading to
20+
information disclosure.
21+
22+
## Details
23+
24+
`Rack::Static#route_file` performs static-route matching using
25+
logic equivalent to:
26+
27+
```ruby
28+
@urls.any? { |url| path.index(url) == 0 }
29+
```
30+
31+
This checks only whether the request path starts with the configured
32+
prefix string. It does not require a path segment boundary after the prefix.
33+
34+
For example, with:
35+
36+
```ruby
37+
use Rack::Static, urls: ["/css", "/js"], root: "public"
38+
```
39+
40+
the following path is matched as intended:
41+
42+
```text
43+
/css/style.css
44+
```
45+
46+
but these paths are also matched:
47+
48+
```text
49+
/css-config.env
50+
/css-backup.sql
51+
/csssecrets.yml
52+
```
53+
54+
If such files exist under the configured static root, Rack forwards
55+
the request to the file server and serves them as static content.
56+
57+
This means a configuration intended to expose only directory trees
58+
such as `/css/...` and `/js/...` may also expose sibling files
59+
whose names begin with those same strings.
60+
61+
## Impact
62+
63+
An attacker can request files under the configured static root whose
64+
names share a configured URL prefix and obtain their contents.
65+
66+
In affected deployments, this may expose configuration files,
67+
secrets, backups, environment files, or other unintended static
68+
content located under the same root directory.
69+
70+
## Mitigation
71+
72+
* Update to a patched version of Rack that enforces a path boundary
73+
when matching configured static URL prefixes.
74+
* Match only paths that are either exactly equal to the configured
75+
prefix or begin with `prefix + "/"`.
76+
* Avoid placing sensitive files under the `Rack::Static` root directory.
77+
* Prefer static URL mappings that cannot overlap with sensitive filenames.
78+
cvss_v3: 7.5
79+
patched_versions:
80+
- "~> 2.2.23"
81+
- "~> 3.1.21"
82+
- ">= 3.2.6"
83+
related:
84+
url:
85+
- https://nvd.nist.gov/vuln/detail/CVE-2026-34785
86+
- https://github.com/rack/rack/security/advisories/GHSA-h2jq-g4cq-5ppq
87+
- https://github.com/advisories/GHSA-h2jq-g4cq-5ppq

gems/rack/CVE-2026-34786.yml

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
---
2+
gem: rack
3+
cve: 2026-34786
4+
ghsa: q4qf-9j86-f5mh
5+
url: https://github.com/rack/rack/security/advisories/GHSA-q4qf-9j86-f5mh
6+
title: 'Rack:: Static header_rules bypass via URL-encoded paths'
7+
date: 2026-04-02
8+
description: |
9+
## Summary
10+
11+
`Rack::Static#applicable_rules` evaluates several `header_rules`
12+
types against the raw URL-encoded `PATH_INFO`, while the underlying
13+
file-serving path is decoded before the file is served. As a result,
14+
a request for a URL-encoded variant of a static path can serve
15+
the same file without the headers that `header_rules` were intended to apply.
16+
17+
In deployments that rely on `Rack::Static` to attach security-relevant
18+
response headers to static content, this can allow an attacker to
19+
bypass those headers by requesting an encoded form of the path.
20+
21+
## Details
22+
23+
`Rack::Static#applicable_rules` matches rule types such as `:fonts`,
24+
`Array`, and `Regexp` directly against the incoming `PATH_INFO`. For example:
25+
26+
```ruby
27+
when :fonts
28+
/\.(?:ttf|otf|eot|woff2|woff|svg)\z/.match?(path)
29+
when Array
30+
/\.(#{rule.join('|')})\z/.match?(path)
31+
when Regexp
32+
rule.match?(path)
33+
```
34+
35+
These checks operate on the raw request path. If the request contains
36+
encoded characters such as `%2E` in place of `.`, the rule may fail
37+
to match even though the file path is later decoded and served
38+
successfully by the static file server.
39+
40+
For example, both of the following requests may resolve to the
41+
same file on disk:
42+
43+
```text
44+
/fonts/test.woff
45+
/fonts/test%2Ewoff
46+
```
47+
48+
but only the unencoded form may receive the headers configured
49+
through `header_rules`.
50+
51+
This creates a canonicalization mismatch between the path used
52+
for header policy decisions and the path ultimately used for file serving.
53+
54+
## Impact
55+
56+
Applications that rely on `Rack::Static` `header_rules` to apply
57+
security-relevant headers to static files may be affected.
58+
59+
In affected deployments, an attacker can request an encoded
60+
variant of a static file path and receive the same file without
61+
the intended headers. Depending on how `header_rules` are used,
62+
this may bypass protections such as clickjacking defenses, content
63+
restrictions, or other response policies applied to static content.
64+
65+
The practical impact depends on the configured rules and the types
66+
of files being served. If `header_rules` are only used for
67+
non-security purposes such as caching, the issue may have limited
68+
security significance.
69+
70+
## Mitigation
71+
72+
* Update to a patched version of Rack that applies `header_rules`
73+
to a decoded path consistently with static file resolution.
74+
* Do not rely solely on `Rack::Static` `header_rules` for
75+
security-critical headers where encoded path variants may
76+
reach the application.
77+
* Prefer setting security headers at the reverse proxy or web server
78+
layer so they apply consistently to both encoded and unencoded path forms.
79+
* Normalize or reject encoded path variants for static content
80+
at the edge, where feasible.
81+
cvss_v3: 5.3
82+
patched_versions:
83+
- "~> 2.2.23"
84+
- "~> 3.1.21"
85+
- ">= 3.2.6"
86+
related:
87+
url:
88+
- https://nvd.nist.gov/vuln/detail/CVE-2026-34786
89+
- https://github.com/rack/rack/security/advisories/GHSA-q4qf-9j86-f5mh
90+
- https://github.com/advisories/GHSA-q4qf-9j86-f5mh

gems/rack/CVE-2026-34826.yml

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
---
2+
gem: rack
3+
cve: 2026-34826
4+
ghsa: x8cg-fq8g-mxfx
5+
url: https://github.com/rack/rack/security/advisories/GHSA-x8cg-fq8g-mxfx
6+
title: Rack's multipart byte range processing allows
7+
denial of service via excessive overlapping ranges
8+
date: 2026-04-02
9+
description: |
10+
## Summary
11+
12+
`Rack::Utils.get_byte_ranges` parses the HTTP `Range` header without
13+
limiting the number of individual byte ranges. Although the existing
14+
fix for CVE-2024-26141 rejects ranges whose total byte coverage
15+
exceeds the file size, it does not restrict the count of ranges.
16+
An attacker can supply many small overlapping ranges such as
17+
`0-0,0-0,0-0,...` to trigger disproportionate CPU, memory, I/O,
18+
and bandwidth consumption per request.
19+
20+
This results in a denial of service condition in Rack file-serving
21+
paths that process multipart byte range responses.
22+
23+
## Details
24+
25+
`Rack::Utils.get_byte_ranges` accepts a comma-separated list of byte
26+
ranges and validates them based on their aggregate size, but does
27+
not impose a limit on how many individual ranges may be supplied.
28+
29+
As a result, a request such as:
30+
31+
```http
32+
Range: bytes=0-0,0-0,0-0,0-0,...
33+
```
34+
35+
can contain thousands of overlapping one-byte ranges while still
36+
satisfying the total-size check added for CVE-2024-26141.
37+
38+
When such a header is processed by Rack’s file-serving code, each
39+
range causes additional work, including multipart response generation,
40+
per-range iteration, file seek and read operations, and temporary
41+
string allocation for response size calculation and output. This
42+
allows a relatively small request header to trigger disproportionately
43+
expensive processing and a much larger multipart response.
44+
45+
The issue is distinct from CVE-2024-26141. That fix prevents range
46+
sets whose total byte coverage exceeds the file size, but does not
47+
prevent a large number of overlapping ranges whose summed size
48+
remains within that limit.
49+
50+
## Impact
51+
52+
Applications that expose file-serving paths with byte range support
53+
may be vulnerable to denial of service.
54+
55+
An unauthenticated attacker can send crafted `Range` headers containing
56+
many small overlapping ranges to consume excessive CPU time, memory,
57+
file I/O, and bandwidth. Repeated requests may reduce application
58+
availability and increase pressure on workers and garbage collection.
59+
60+
## Mitigation
61+
62+
* Update to a patched version of Rack that limits the number
63+
of accepted byte ranges.
64+
* Reject or normalize multipart byte range requests containing
65+
excessive range counts.
66+
* Consider disabling multipart range support where it is not required.
67+
* Apply request filtering or header restrictions at the reverse
68+
proxy or application boundary to limit abusive `Range` headers.
69+
cvss_v3: 5.3
70+
patched_versions:
71+
- "~> 2.2.23"
72+
- "~> 3.1.21"
73+
- ">= 3.2.6"
74+
related:
75+
url:
76+
- https://nvd.nist.gov/vuln/detail/CVE-2026-34826
77+
- https://github.com/rack/rack/security/advisories/GHSA-x8cg-fq8g-mxfx
78+
- https://github.com/advisories/GHSA-x8cg-fq8g-mxfx

0 commit comments

Comments
 (0)