CVE-2026-34786
Medium · 5.3CVSS
5.3
EPSS
0.3%
Published
Apr 2, 2026
CISA due date
—
Cloudanix analysis
Some Ruby web applications may serve the same static file without its intended browser safety settings when the file is requested using an encoded web address.
- Exploitation
- Remote Unauthenticated
- Attacker needs
- None
- Complexity
- Low
- Impact
- Data Tampering
- Component
- Web Framework
- Class
- Improper Input Validation
- Remediation
- Upgrade
- Effort
- Medium
- Patch risk
- Low
What it actually does
CVE-2026-34786 is an input normalization flaw in Rack::Static. Before Rack 2.2.23, 3.1.21, and 3.2.6, Rack evaluates header_rules against the raw URL-encoded PATH_INFO, but decodes the path when selecting and serving the underlying static file. This mismatch means two requests can address the same file while only one matches the configured header rule. If an application relies on Rack::Static header_rules to add security-relevant headers to static files, an attacker can request an encoded path variant and receive the same content without intended headers. The direct impact is integrity reduction of HTTP responses, specifically bypass of headers such as Content-Security-Policy, X-Frame-Options, Cache-Control, X-Content-Type-Options, Referrer-Policy, or similar policy headers when they are applied through Rack::Static rules.
Why it matters to the business
The likely business impact is weakening of browser-side protections for static assets. In affected deployments, files that operators expect to be protected by response headers may be served without those protections when requested through encoded URLs. This can increase exposure to secondary risks such as clickjacking, unsafe caching, MIME sniffing, relaxed content loading, or disclosure through missing cache/privacy controls depending on which headers were configured. The vulnerability is network-reachable, requires no authentication, and is low-complexity, but it does not by itself provide code execution, data theft, or service disruption. EPSS is low and it is not listed in CISA KEV, so prioritization should be risk-based, with higher urgency for internet-facing Ruby/Rack applications that use Rack::Static header_rules for security controls.
How an attack unfolds
An attacker first identifies a Ruby application or framework component using vulnerable Rack versions and serving static files through Rack::Static. They then look for security headers that are applied only to specific static paths by header_rules. Because Rack compares those rules against the raw, URL-encoded PATH_INFO but serves files using a decoded path, the attacker crafts a URL-encoded equivalent of a protected static path, such as encoding one or more path characters. The decoded path still resolves to the intended static file, so Rack serves the same content, but the header rule may not match the raw encoded request path. The response is therefore returned without the intended security headers. The attacker can then use that downgraded response in a broader browser-based attack scenario, such as framing content that should have been protected by frame restrictions, causing content to be interpreted under weaker MIME handling, or bypassing cache-control expectations.
How to fix it
Upgrade Rack to a patched version: 2.2.23 or later for the 2.2.x line, 3.1.21 or later for the 3.1.x line, or 3.2.6 or later for the 3.2.x line. If using Bundler, update the rack gem constraint and regenerate the lockfile, then rebuild and redeploy affected applications and containers. Where immediate upgrade is not possible, avoid relying on Rack::Static header_rules as the only mechanism for security headers on static content. Apply security headers at a layer that observes normalized request paths consistently, such as the reverse proxy, CDN, application middleware, or web server configuration. As a defense-in-depth measure, normalize or reject ambiguous percent-encoded static paths at the edge where feasible, and ensure critical security headers are applied broadly rather than only to narrow path rules.
How to confirm the fix worked
Confirm the deployed Rack version is patched by checking dependency manifests and runtime package versions, such as Gemfile.lock, bundle list, bundle info rack, or equivalent build artifact metadata. Validate behavior by selecting a static file that should receive security headers from Rack::Static header_rules, requesting it by its normal path, and recording the response headers. Then request URL-encoded variants of the same path that decode to the same file and verify that the same security headers are still present. Also test through the full production delivery path, including CDN, reverse proxy, load balancer, and application tier, because headers may be added or removed at multiple layers. Vulnerability scanners can supplement this by comparing response-header differences between canonical and percent-encoded static asset URLs.
Typical attack path
- Identify an internet-accessible Ruby/Rack application that serves static files through Rack::Static.
- Determine or infer that static response headers are applied using Rack::Static header_rules.
- Request a protected static asset normally and observe the expected security headers.
- Craft an equivalent URL using percent-encoding in the path so the decoded path resolves to the same file.
- Request the encoded path and compare the response headers to confirm that the intended header_rules were bypassed.
- Abuse the response without the expected headers as part of a broader browser-side attack such as clickjacking, unsafe caching, or weakened content handling.
How to detect it
To assess prior exploitation, review web server, reverse proxy, CDN, WAF, and application access logs for percent-encoded requests to static-file paths that normally carry security headers. Focus on paths containing encoded characters such as %2e, %2f, %5c, %20, %2d, %5f, or encoded letters within asset filenames, especially where the decoded path maps to an existing static asset. Compare historical responses, if response-header logging is available, to identify cases where canonical requests contained security headers but encoded-path requests did not. Investigate repeated probing from the same source across common static directories such as /assets/, /public/, /static/, /packs/, /images/, /javascripts/, /stylesheets/, /css/, and /js/. Since this vulnerability leaves no unique server-side artifact beyond HTTP request patterns and possible response-header differences, detection is primarily log-based and behavioral. Also review CDN cache entries, WAF events, and security monitoring telemetry for unusual encoded static-asset requests, clickjacking probes, iframe embedding attempts, or referrers from untrusted pages shortly after such requests.
- %2e
- %2E
- %2f
- %2F
- %5c
- %5C
- %20
- %2d
- %2D
- %5f
- %5F
- GET /assets/%
- GET /public/%
- GET /static/%
- GET /packs/%
- GET /images/%
- GET /javascripts/%
- GET /stylesheets/%
- GET /css/%
- GET /js/%
- PATH_INFO
What your security team should do
- Inventory Ruby applications and services that include the rack gem and identify versions earlier than 2.2.23, 3.1.21, or 3.2.6.
- Prioritize remediation for internet-facing applications that serve static files through Rack::Static and rely on header_rules for security headers.
- Upgrade Rack to the appropriate fixed release line and redeploy all affected application images, packages, and runtime environments.
- Move critical security headers to a centralized enforcement point such as a reverse proxy, CDN, or global application middleware where possible.
- Add regression tests that compare security headers on canonical and percent-encoded static asset paths.
- Review access logs for encoded requests to static assets, especially requests followed by browser-based attack patterns such as framing probes or unusual referrers.
- Because this issue is not in CISA KEV, has low EPSS, and has no known mature public exploitation indicated, handle as a normal-priority patch unless the application depends heavily on path-specific static security headers.
The record
Rack is a modular Ruby web server interface. Prior to versions 2.2.23, 3.1.21, and 3.2.6, 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. This issue has been patched in versions 2.2.23, 3.1.21, and 3.2.6.
Affected packages
| Ecosystem | Package | Introduced | Fixed |
|---|---|---|---|
| openSUSE:Tumbleweed | rubygem-rack-2.2 | 0 | 2.2.23-1.1 |
Related vulnerabilities
- CVE-2026-34829 Rack is a modular Ruby web server interface. Also affects rubygem-rack-2.2
- CVE-2026-34831 Rack is a modular Ruby web server interface. Also affects rubygem-rack-2.2
- CVE-2026-34830 Rack is a modular Ruby web server interface. Also affects rubygem-rack-2.2
- CVE-2026-34826 Rack is a modular Ruby web server interface. Also affects rubygem-rack-2.2
- CVE-2026-34785 Rack is a modular Ruby web server interface. Also affects rubygem-rack-2.2
- CVE-2026-34763 Rack is a modular Ruby web server interface. Also affects rubygem-rack-2.2
- CVE-2026-34230 Rack is a modular Ruby web server interface. Also affects rubygem-rack-2.2
- CVE-2026-26961 Rack is a modular Ruby web server interface. Also affects rubygem-rack-2.2