GHSA-h2jq-g4cq-5ppq CVE-2026-34785
Rack::Static prefix matching can expose unintended files under the static root
- Severity
- 7.5 / 10
- High · CVSS 3.1
- Exploit chance (EPSS)
- 0.39%
- Chance of exploitation in the next 30 days. Higher than 33.64% of scored vulnerabilities.
- Known exploited
- No
- Not in CISA's catalog
- Weakness
- CWE-187 Partial String Comparison
- CWE-200 Exposure of Sensitive Information to an Unauthorized Actor
- Fix
2.2.23- Upgrade rack to this version or later
Description
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:
@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:
use Rack::Static, urls: ["/css", "/js"], root: "public"
the following path is matched as intended:
/css/style.css
but these paths are also matched:
/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::Staticroot directory. - Prefer static URL mappings that cannot overlap with sensitive filenames.
Affected versions
RubyGems
| Package | Vulnerable | Fixed in |
|---|---|---|
| rack | < 2.2.23 |
2.2.23 |
| rack | >= 3.0.0.beta1, < 3.1.21 |
3.1.21 |
| rack | >= 3.2.0, < 3.2.6 |
3.2.6 |
How to fix
Move to the fixed version or later with your package manager, update the lockfile, and run your tests. If the package only arrives through another dependency, upgrade that dependency first. If none of its releases pulls a fixed version yet, force the version with your package manager's override.
rack RubyGems → 2.2.23
- bundler
bundle update rack # Gemfile: gem "rack", ">= 2.2.23"
Severity breakdown
CVSS 3.1 7.5
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N
- Attack vector
- Network
- Attack complexity
- Low
- Privileges required
- None
- User interaction
- None
- Scope
- Unchanged
- Confidentiality
- High
- Integrity
- None
- Availability
- None
Weakness
CWE-187: Partial String Comparison
The product performs a comparison that only examines a portion of a factor before determining whether there is a match, such as a substring, leading to resultant weaknesses.
How to prevent it
- Testing: Thoroughly test the comparison scheme before deploying code into production. Perform positive testing as well as negative testing.
CWE-200: Exposure of Sensitive Information to an Unauthorized Actor
The product exposes sensitive information to an actor that is not explicitly authorized to have access to that information.
How to prevent it
- Architecture and Design: Compartmentalize the system to have "safe" areas where trust boundaries can be unambiguously drawn. Do not allow sensitive data to go outside of the trust boundary and always be careful when interfacing with a compartment outside of the safe area. Ensure that appropriate compartmentalization is built into the system design, and the compartmentalization allows for and reinforces privilege separation functionality. Architects and designers should rely on the principle of least privilege to decide the appropriate time to use privileges and the time to drop privileges.
References
Advisories
Packages
Other links
Timeline
- Published
- Last updated by the source
- Latest EPSS score
Related advisories
| Advisory | Severity | Why it's related |
|---|---|---|
| GHSA-g2pf-xv49-m2h5 Rack::Request accepts invalid Host characters, enabling host allowlist bypass | Medium | Also affects rack |
| GHSA-v6x5-cg8r-vv6x Rack's multipart header parsing allows Denial of Service via escape-heavy quoted parameters | High | Also affects rack |
| GHSA-qfgr-crr9-7r49 Rack: Forwarded Header semicolon injection enables Host and Scheme spoofing | Medium | Also affects rack |
| GHSA-rx22-g9mx-qrhv Rack's improper unfolding of folded multipart headers preserves CRLF in parsed parameter values | Medium | Also affects rack |
| GHSA-q2ww-5357-x388 Rack has Content-Length mismatch in Rack::Files error responses | Medium | Also affects rack |
| GHSA-qv7j-4883-hwh7 Rack::Sendfile header-based X-Accel-Mapping regex injection enables unauthorized X-Accel-Redirect | High | Also affects rack |
| GHSA-8vqr-qjwx-82mw Rack's multipart parsing without Content-Length header allows unbounded chunked file uploads | High | Also affects rack |
| GHSA-x8cg-fq8g-mxfx Rack's multipart byte range processing allows denial of service via excessive overlapping ranges | High | Also affects rack |
MergeHarbor checks every repository's dependencies against this database, ranks what matters by exploitability and reachability, routes it to the owning team and opens the fix pull request.
Check your repos with MergeHarbor