GHSA-wvg4-6p58-3gh3: Rack: Rack::Static header_rules bypass via dot-segment normalization mismatch

  • Severity: MEDIUM
  • CVE: CVE-2026-125110
  • Ecosystems: rubygems, rubygems, rubygems
  • Packages: rack, rack, rack

## Summary

`Rack::Static` normalizes the request path with `Utils.clean_path_info` when deciding which file to serve, but matches `header_rules` against a path that is only URL-decoded. A request containing dot segments, raw or percent-encoded, is served the normalized target file while the header rules for that file’s location are not applied.

This allows an attacker to receive a protected static file without the security headers configured for it.

## Details

`Rack::Static#call` computes the served path as `Utils.clean_path_info(Utils.unescape_path(path))`. `Rack::Static#applicable_rules` applies only `Utils.unescape_path` before testing string and regular expression rules. A request for `/assets/../uploads/file.html` or `/assets/..%2fuploads/file.html` is served as `uploads/file.html`, but the decoded path `/assets/../uploads/file.html` does not start with `uploads`, so a rule scoped to that directory never matches.

The fix for CVE-2026-34786 (GHSA-q4qf-9j86-f5mh) added URL decoding to rule matching but did not add dot segment normalization, so versions that include that fix remain affected.

## Impact

Applications that use `Rack::Static` `header_rules` to attach security-relevant headers to particular paths or file types are affected. An unauthenticated attacker who knows the path of a protected file can request it through a dot segment path and receive it without those headers, for example without `Content-Disposition: attachment` or a restrictive `Content-Security-…

Source: GitHub Security Advisories · 2026-11-10