{"id":"CVE-2026-125110","aliases":["GHSA-wvg4-6p58-3gh3"],"title":"Rack: Rack::Static header_rules bypass via dot-segment normalization mismatch","titleSource":"OSV","descriptionSource":"OSV","declaredSeverity":"MODERATE","description":"## Summary\n\n`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.\n\nThis allows an attacker to receive a protected static file without the security headers configured for it.\n\n## Details\n\n`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.\n\nThe 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.\n\n## Impact\n\nApplications 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-Policy` that prevents uploaded HTML from rendering inline. The file itself is served unchanged. Applications that do not use path-specific `header_rules` are not affected.\n\n## Mitigation\n\n* Update to a patched version of Rack in which `header_rules` are matched against the same normalized path used to serve the file.\n* Reject requests containing dot segments at a reverse proxy or application boundary.\n* Do not rely solely on `Rack::Static` `header_rules` to prevent inline rendering of untrusted uploads; serve them from a separate origin.\n\n## Credit\n* Reporter and Remediation developer","severity":"medium","score":5.3,"published":"2026-11-09T22:00:40.811Z","modified":"2026-11-14T02:25:26.839Z","withdrawn":false,"knownExploited":false,"affected":[{"ecosystem":"RubyGems","name":"rack","sources":[{"name":"OSV · GHSA-wvg4-6p58-3gh3","url":"https://osv.dev/vulnerability/GHSA-wvg4-6p58-3gh3"}],"ranges":[{"events":[{"introduced":"0"},{"fixed":"2.2.25"}],"type":"ECOSYSTEM"}],"versions":["0.1.0","0.2.0","0.3.0","0.4.0","0.9.0","0.9.1","1.0.0","1.0.1","1.1.0","1.1.1","1.1.1.pre","1.1.2","1.1.3","1.1.4","1.1.5","1.1.6","1.2.0","1.2.1","1.2.2","1.2.3","1.2.4","1.2.5","1.2.6","1.2.7","1.2.8","1.3.0","1.3.0.beta","1.3.0.beta2","1.3.1","1.3.10","1.3.2","1.3.3","1.3.4","1.3.5","1.3.6","1.3.7","1.3.8","1.3.9","1.4.0","1.4.1","1.4.2","1.4.3","1.4.4","1.4.5","1.4.6","1.4.7","1.5.0","1.5.0.beta.1","1.5.0.beta.2","1.5.1","1.5.2","1.5.3","1.5.4","1.5.5","1.6.0","1.6.0.beta","1.6.0.beta2","1.6.1","1.6.10","1.6.11","1.6.12","1.6.13","1.6.2","1.6.3","1.6.4","1.6.5","1.6.6","1.6.7","1.6.8","1.6.9","2.0.0.alpha","2.0.0.rc1","2.0.1","2.0.2","2.0.3","2.0.4","2.0.5","2.0.6","2.0.7","2.0.8","2.0.9","2.0.9.1","2.0.9.2","2.0.9.3","2.0.9.4","2.1.0","2.1.1","2.1.2","2.1.3","2.1.4","2.1.4.1","2.1.4.2","2.1.4.3","2.1.4.4","2.2.0","2.2.1","2.2.10","2.2.11","2.2.12","2.2.13","2.2.14","2.2.15","2.2.16","2.2.17","2.2.18","2.2.19","2.2.2","2.2.20","2.2.21","2.2.22","2.2.23","2.2.24","2.2.3","2.2.3.1","2.2.4","2.2.5","2.2.6","2.2.6.1","2.2.6.2","2.2.6.3","2.2.6.4","2.2.7","2.2.8","2.2.8.1","2.2.9"],"fixed":["2.2.25"]},{"ecosystem":"RubyGems","name":"rack","sources":[{"name":"OSV · GHSA-wvg4-6p58-3gh3","url":"https://osv.dev/vulnerability/GHSA-wvg4-6p58-3gh3"}],"ranges":[{"events":[{"introduced":"3.0.0"},{"fixed":"3.1.23"}],"type":"ECOSYSTEM"}],"versions":["3.0.0","3.0.1","3.0.10","3.0.11","3.0.12","3.0.13","3.0.14","3.0.15","3.0.16","3.0.17","3.0.18","3.0.2","3.0.3","3.0.4","3.0.4.1","3.0.4.2","3.0.5","3.0.6","3.0.6.1","3.0.7","3.0.8","3.0.9","3.0.9.1","3.1.0","3.1.1","3.1.10","3.1.11","3.1.12","3.1.13","3.1.14","3.1.15","3.1.16","3.1.17","3.1.18","3.1.19","3.1.2","3.1.20","3.1.21","3.1.22","3.1.3","3.1.4","3.1.5","3.1.6","3.1.7","3.1.8","3.1.9"],"fixed":["3.1.23"]},{"ecosystem":"RubyGems","name":"rack","sources":[{"name":"OSV · GHSA-wvg4-6p58-3gh3","url":"https://osv.dev/vulnerability/GHSA-wvg4-6p58-3gh3"}],"ranges":[{"events":[{"introduced":"3.2.0"},{"fixed":"3.2.8"}],"type":"ECOSYSTEM"}],"versions":["3.2.0","3.2.1","3.2.2","3.2.3","3.2.4","3.2.5","3.2.6","3.2.7"],"fixed":["3.2.8"]}],"sourceAffected":[],"references":["https://github.com/rack/rack/security/advisories/GHSA-wvg4-6p58-3gh3","https://nvd.nist.gov/vuln/detail/CVE-2026-125110","https://github.com/rack/rack/commit/18a07fe553afb4d8a678d6a948cd6ba1e11e28be","https://github.com/rack/rack/commit/9d7f19484ffd5ed5e032678c26ee6eff96d3a0a3","https://github.com/rack/rack/commit/e88097ccb88be44d06d47b42daffe04929516ee4","https://github.com/rack/rack","https://github.com/rubysec/ruby-advisory-db/blob/master/gems/rack/GHSA-wvg4-6p58-3gh3.yml"],"sources":[{"name":"OSV","id":"GHSA-wvg4-6p58-3gh3","modified":"2026-11-10T19:00:04.397956603Z","url":"https://osv.dev/vulnerability/GHSA-wvg4-6p58-3gh3"},{"name":"CVE","id":"CVE-2026-125110","modified":"2026-11-14T02:25:26.839Z","url":"https://www.cve.org/CVERecord?id=CVE-2026-125110"}],"assessments":[{"source":"OSV","vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:N","score":5.3},{"source":"GitHub_M","vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:N","score":5.3}],"cve":{"records":[{"id":"CVE-2026-125110","source":"GitHub_M","state":"PUBLISHED","reasons":[],"replacements":[],"disputed":false,"unsupportedWhenAssigned":false,"reserved":"2026-11-09T17:45:35.935Z","published":"2026-11-09T22:00:40.811Z","modified":"2026-11-14T02:25:26.839Z"}],"publishers":[{"name":"GitHub_M","role":"CNA","organizationId":"a0819718-46f1-4df5-94e2-005712e83aaa","modified":"2026-11-09T22:00:40.811Z"},{"name":"CISA-ADP","role":"ADP","organizationId":"134c704f-9b21-4f2e-91b3-4a467353bcc0","modified":"2026-11-14T02:25:26.839Z"}],"references":[{"url":"https://github.com/rack/rack/security/advisories/GHSA-wvg4-6p58-3gh3","tags":["x_refsource_CONFIRM"],"source":"GitHub_M"},{"url":"https://github.com/rack/rack/commit/18a07fe553afb4d8a678d6a948cd6ba1e11e28be","tags":["x_refsource_MISC"],"source":"GitHub_M"},{"url":"https://github.com/rack/rack/commit/9d7f19484ffd5ed5e032678c26ee6eff96d3a0a3","tags":["x_refsource_MISC"],"source":"GitHub_M"},{"url":"https://github.com/rack/rack/commit/e88097ccb88be44d06d47b42daffe04929516ee4","tags":["x_refsource_MISC"],"source":"GitHub_M"}],"weaknesses":[{"id":"CWE-180","description":"CWE-180: Incorrect Behavior Order: Validate Before Canonicalize","source":"GitHub_M"}],"applicability":[],"prioritization":[{"source":"CISA-ADP","type":"SSVC","role":"CISA Coordinator","timestamp":"2026-11-14T02:25:17.811506Z","decisions":[{"name":"Exploitation","value":"none"},{"name":"Automatable","value":"yes"},{"name":"Technical Impact","value":"partial"}]}]},"products":[{"vendor":"rack","name":"rack","platforms":[],"versions":[{"version":"< 2.2.25","status":"affected"},{"version":">= 3.0, < 3.1.23","status":"affected"},{"version":">= 3.2, < 3.2.8","status":"affected"}],"cpes":[],"source":"GitHub_M","url":"https://www.cve.org/CVERecord?id=CVE-2026-125110"}],"remediation":[],"observedAt":"2026-11-14T03:20:52.178Z","kev":{"status":"not-listed","checkedAt":"2026-11-15T04:05:32.009Z"},"coverage":[{"source":"NVD","status":"no-result","checkedAt":"2026-11-09T23:35:38.108Z","attemptedAt":"2026-11-09T23:35:38.108Z"},{"source":"GHSA","status":"no-result","checkedAt":"2026-11-09T23:35:35.248Z","attemptedAt":"2026-11-09T23:35:35.248Z"},{"source":"EUVD","status":"available","checkedAt":"2026-11-09T23:35:35.801Z","attemptedAt":"2026-11-09T23:35:35.801Z"},{"source":"EPSS","status":"no-result","checkedAt":"2026-11-09T23:35:34.979Z","attemptedAt":"2026-11-09T23:35:34.979Z"}],"evidence":[{"source":"ENISA EUVD","id":"EUVD-2026-120484","url":"https://euvd.enisa.europa.eu/vulnerability/EUVD-2026-120484","modified":"Nov 9, 2026, 10:00:40 PM","score":5.3,"vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:N","checkedAt":"2026-11-09T23:35:35.801Z"}],"aiSummary":null}