{"id":"CVE-2026-25500","aliases":["DEBIAN-CVE-2026-25500","DLA-4505-1","DSA-6180-1","EUVD-2026-7916","GHSA-whrj-4476-wvmp","MGASA-2026-0075","UBUNTU-CVE-2026-25500","openSUSE-SU-2026:10286-1"],"status":"published","title":"Rack's Stored XSS in Rack::Directory via javascript: filenames rendered into anchor href","description":"Rack is a modular Ruby web server interface. Prior to versions 2.2.22, 3.1.20, and 3.2.5, `Rack::Directory` generates an HTML directory index where each file entry is rendered as a clickable link. If a file exists on disk whose basename starts with the `javascript:` scheme (e.g. `javascript:alert(1)`), the generated index contains an anchor whose `href` is exactly `javascript:alert(1)`. Clicking the entry executes JavaScript in the browser (demonstrated with `alert(1)`). Versions 2.2.22, 3.1.20, and 3.2.5 fix the issue.","severity":{"version":"3.1","score":5.4,"vector":"CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:C/C:L/I:L/A:N","level":"medium","assessor":"cna","from":"cve"},"epss":{"day":"2026-11-11","score":0.00269,"percentile":0.19285,"model":"v2026.06.15"},"facts":{"in_kev":false,"known_exploited":false,"public_exploit":false,"fix_available":true},"cwes":["CWE-79"],"published":"2026-02-17T18:46:35Z","modified":"2026-10-28T02:31:08Z","fixes":[{"ecosystem":"RubyGems","package":"rack","fixed_in":["2.2.22","3.1.20","3.2.5"],"sources":["ghsa","osv"]},{"ecosystem":"Debian:12","package":"ruby-rack","fixed_in":["2.2.22-0+deb12u1"],"sources":["osv"]},{"ecosystem":"Debian:13","package":"ruby-rack","fixed_in":["3.1.20-0+deb13u1"],"sources":["osv"]},{"ecosystem":"Debian:14","package":"ruby-rack","fixed_in":["3.2.5-1"],"sources":["osv"]},{"ecosystem":"Ubuntu:Pro:20.04:LTS","package":"ruby-rack","fixed_in":["2.0.7-2ubuntu0.1+esm9"],"sources":["osv"]},{"ecosystem":"Ubuntu:Pro:22.04:LTS","package":"ruby-rack","fixed_in":["2.1.4-5ubuntu1.2+esm2"],"sources":["osv"]},{"ecosystem":"Ubuntu:24.04:LTS","package":"ruby-rack","fixed_in":["2.2.7-1ubuntu0.6"],"sources":["osv"]},{"ecosystem":"Ubuntu:25.10","package":"ruby-rack","fixed_in":["3.1.16-0.1ubuntu0.2"],"sources":["osv"]},{"ecosystem":"Ubuntu:26.10","package":"ruby-rack","fixed_in":["3.2.4-1ubuntu1"],"sources":["osv"]},{"ecosystem":"Ubuntu:26.04:LTS","package":"ruby-rack","fixed_in":["3.2.4-1ubuntu1"],"sources":["osv"]}],"affected":[{"source":"ghsa","ecosystem":"RubyGems","package":"rack","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"2.2.22"}]}]},{"source":"ghsa","ecosystem":"RubyGems","package":"rack","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"3.0.0.beta1"},{"fixed":"3.1.20"}]}]},{"source":"ghsa","ecosystem":"RubyGems","package":"rack","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"3.2.0"},{"fixed":"3.2.5"}]}]},{"source":"osv","ecosystem":"Debian:12","package":"ruby-rack","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"2.2.22-0+deb12u1"}]}],"versions":["2.2.13-1~deb12u1","2.2.20-0+deb12u1","2.2.6.4-1","2.2.6.4-1+deb12u1","2.2.7-1","2.2.7-1.1"]},{"source":"osv","ecosystem":"Debian:13","package":"ruby-rack","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"3.1.20-0+deb13u1"}]}],"versions":["3.1.16-0.1","3.1.18-1","3.1.18-1~deb13u1"]},{"source":"osv","ecosystem":"Debian:14","package":"ruby-rack","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"3.2.5-1"}]}],"versions":["3.1.16-0.1","3.1.18-1","3.1.18-1~deb13u1","3.2.4-1"]},{"source":"osv","ecosystem":"Debian:11","package":"ruby-rack","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"2.1.4-3+deb11u5"}]}],"versions":["2.1.4-3","2.1.4-3+deb11u1","2.1.4-3+deb11u2","2.1.4-3+deb11u3","2.1.4-3+deb11u4"],"bundled":2},{"source":"osv","ecosystem":"Debian:12","package":"ruby-rack","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"2.2.22-0+deb12u1"}]}],"versions":["2.2.13-1~deb12u1","2.2.20-0+deb12u1","2.2.6.4-1","2.2.6.4-1+deb12u1","2.2.7-1","2.2.7-1.1"],"bundled":2},{"source":"osv","ecosystem":"Debian:13","package":"ruby-rack","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"3.1.20-0+deb13u1"}]}],"versions":["3.1.16-0.1","3.1.18-1","3.1.18-1~deb13u1"],"bundled":2},{"source":"osv","ecosystem":"RubyGems","package":"rack","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"2.2.22"}]}],"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.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"]},{"source":"osv","ecosystem":"RubyGems","package":"rack","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"3.0.0.beta1"},{"fixed":"3.1.20"}]}],"versions":["3.0.0","3.0.0.beta1","3.0.0.rc1","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.3","3.1.4","3.1.5","3.1.6","3.1.7","3.1.8","3.1.9"]},{"source":"osv","ecosystem":"RubyGems","package":"rack","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"3.2.0"},{"fixed":"3.2.5"}]}],"versions":["3.2.0","3.2.1","3.2.2","3.2.3","3.2.4"]},{"source":"osv","ecosystem":"Mageia:9","package":"ruby-rack","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"2.2.22-1.mga9"}]}],"bundled":2},{"source":"osv","ecosystem":"Ubuntu:Pro:14.04:LTS","package":"ruby-rack","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"}]}],"versions":["1.5.2-1","1.5.2-1ubuntu0.1~esm1","1.5.2-3+deb8u3ubuntu1~esm2","1.5.2-3+deb8u3ubuntu1~esm3","1.5.2-3+deb8u3ubuntu1~esm4","1.5.2-3+deb8u3ubuntu1~esm6","1.5.2-3+deb8u3ubuntu1~esm7","1.5.2-3+deb8u3ubuntu1~esm8","1.5.2-3+deb8u3ubuntu1~esm9","1.5.2-3+deb8u3ubuntu1~esm10","1.5.2-3+deb8u3ubuntu1~esm11"]},{"source":"osv","ecosystem":"Ubuntu:Pro:16.04:LTS","package":"ruby-rack","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"}]}],"versions":["1.5.2-4","1.6.4-2","1.6.4-3","1.6.4-3ubuntu0.1","1.6.4-3ubuntu0.2","1.6.4-3ubuntu0.2+esm1","1.6.4-3ubuntu0.2+esm2","1.6.4-3ubuntu0.2+esm4","1.6.4-3ubuntu0.2+esm5","1.6.4-3ubuntu0.2+esm6","1.6.4-3ubuntu0.2+esm7","1.6.4-3ubuntu0.2+esm8","1.6.4-3ubuntu0.2+esm9","1.6.4-3ubuntu0.2+esm10"]},{"source":"osv","ecosystem":"Ubuntu:Pro:18.04:LTS","package":"ruby-rack","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"}]}],"versions":["1.6.4-4","1.6.4-4ubuntu0.1","1.6.4-4ubuntu0.2","1.6.4-4ubuntu0.2+esm1","1.6.4-4ubuntu0.2+esm2","1.6.4-4ubuntu0.2+esm4","1.6.4-4ubuntu0.2+esm5","1.6.4-4ubuntu0.2+esm6","1.6.4-4ubuntu0.2+esm7","1.6.4-4ubuntu0.2+esm8","1.6.4-4ubuntu0.2+esm9","1.6.4-4ubuntu0.2+esm10"]},{"source":"osv","ecosystem":"Ubuntu:Pro:20.04:LTS","package":"ruby-rack","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"2.0.7-2ubuntu0.1+esm9"}]}],"versions":["2.0.6-3","2.0.7-2","2.0.7-2ubuntu0.1","2.0.7-2ubuntu0.1+esm1","2.0.7-2ubuntu0.1+esm2","2.0.7-2ubuntu0.1+esm3","2.0.7-2ubuntu0.1+esm4","2.0.7-2ubuntu0.1+esm5","2.0.7-2ubuntu0.1+esm6","2.0.7-2ubuntu0.1+esm7","2.0.7-2ubuntu0.1+esm8"]},{"source":"osv","ecosystem":"Ubuntu:Pro:22.04:LTS","package":"ruby-rack","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"2.1.4-5ubuntu1.2+esm2"}]}],"versions":["2.1.4-3","2.1.4-4","2.1.4-5","2.1.4-5ubuntu1","2.1.4-5ubuntu1+esm2","2.1.4-5ubuntu1+esm3","2.1.4-5ubuntu1+esm4","2.1.4-5ubuntu1+esm5","2.1.4-5ubuntu1.1","2.1.4-5ubuntu1.1+esm1","2.1.4-5ubuntu1.1+esm2","2.1.4-5ubuntu1.2","2.1.4-5ubuntu1.2+esm1"]},{"source":"osv","ecosystem":"Ubuntu:24.04:LTS","package":"ruby-rack","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"2.2.7-1ubuntu0.6"}]}],"versions":["2.2.4-3","2.2.7-1","2.2.7-1ubuntu0.1","2.2.7-1ubuntu0.2","2.2.7-1ubuntu0.3","2.2.7-1ubuntu0.4","2.2.7-1ubuntu0.5"]},{"source":"osv","ecosystem":"Ubuntu:25.10","package":"ruby-rack","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"3.1.16-0.1ubuntu0.2"}]}],"versions":["2.2.7-1.1","3.1.16-0.1","3.1.16-0.1ubuntu0.1"]},{"source":"osv","ecosystem":"Ubuntu:26.10","package":"ruby-rack","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"3.2.4-1ubuntu1"}]}]},{"source":"osv","ecosystem":"Ubuntu:26.04:LTS","package":"ruby-rack","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"3.2.4-1ubuntu1"}]}],"versions":["3.1.16-0.1","3.1.18-1","3.1.18-1build1"]},{"source":"osv","ecosystem":"openSUSE:Tumbleweed","package":"rubygem-rack-2.2","ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"2.2.22-1.1"}]}],"bundled":27}],"products":[{"vendor":"rack","product":"rack"}],"references":[{"url":"https://github.com/rack/rack/security/advisories/GHSA-whrj-4476-wvmp","tags":["x_refsource_CONFIRM","Exploit","Mitigation","Vendor Advisory","advisory","web","report"]},{"url":"https://github.com/rack/rack/commit/f2f225f297b99fbee3d9f51255d41f601fc40aff","tags":["x_refsource_MISC","Patch","fix","web"]},{"url":"https://nvd.nist.gov/vuln/detail/CVE-2026-25500","tags":["advisory"]},{"url":"https://github.com/rubysec/ruby-advisory-db/blob/master/gems/rack/CVE-2026-25500.yml","tags":["web"]},{"url":"https://github.com/advisories/GHSA-whrj-4476-wvmp"},{"url":"https://github.com/CVEProject/cvelistV5/tree/main/cves/2026/25xxx/CVE-2026-25500.json","tags":["advisory"]},{"url":"https://security-tracker.debian.org/tracker/CVE-2026-25500","tags":["advisory"]},{"url":"https://github.com/rack/rack","tags":["package"]},{"url":"https://advisories.mageia.org/MGASA-2026-0075.html","tags":["advisory"]},{"url":"https://bugs.mageia.org/show_bug.cgi?id=35285","tags":["report"]},{"url":"https://lists.debian.org/debian-security-announce/2026/msg00089.html","tags":["web"]},{"url":"https://ubuntu.com/security/CVE-2026-25500","tags":["report"]},{"url":"https://www.cve.org/CVERecord?id=CVE-2026-25500","tags":["report"]},{"url":"https://ubuntu.com/security/notices/USN-8066-1","tags":["advisory"]},{"url":"","tags":["advisory"]},{"url":"https://www.suse.com/security/cve/CVE-2013-0262","tags":["web"]},{"url":"https://www.suse.com/security/cve/CVE-2013-0263","tags":["web"]},{"url":"https://www.suse.com/security/cve/CVE-2015-3225","tags":["web"]},{"url":"https://www.suse.com/security/cve/CVE-2018-16471","tags":["web"]},{"url":"https://www.suse.com/security/cve/CVE-2019-16782","tags":["web"]},{"url":"https://www.suse.com/security/cve/CVE-2020-8184","tags":["web"]},{"url":"https://www.suse.com/security/cve/CVE-2022-30122","tags":["web"]},{"url":"https://www.suse.com/security/cve/CVE-2022-30123","tags":["web"]},{"url":"https://www.suse.com/security/cve/CVE-2022-44570","tags":["web"]},{"url":"https://www.suse.com/security/cve/CVE-2022-44571","tags":["web"]},{"url":"https://www.suse.com/security/cve/CVE-2022-44572","tags":["web"]},{"url":"https://www.suse.com/security/cve/CVE-2023-27530","tags":["web"]},{"url":"https://www.suse.com/security/cve/CVE-2023-27539","tags":["web"]},{"url":"https://www.suse.com/security/cve/CVE-2024-25126","tags":["web"]},{"url":"https://www.suse.com/security/cve/CVE-2024-26141","tags":["web"]},{"url":"https://www.suse.com/security/cve/CVE-2024-26146","tags":["web"]},{"url":"https://www.suse.com/security/cve/CVE-2025-25184","tags":["web"]},{"url":"https://www.suse.com/security/cve/CVE-2025-27111","tags":["web"]},{"url":"https://www.suse.com/security/cve/CVE-2025-27610","tags":["web"]},{"url":"https://www.suse.com/security/cve/CVE-2025-46727","tags":["web"]},{"url":"https://www.suse.com/security/cve/CVE-2025-59830","tags":["web"]},{"url":"https://www.suse.com/security/cve/CVE-2025-61770","tags":["web"]},{"url":"https://www.suse.com/security/cve/CVE-2025-61771","tags":["web"]},{"url":"https://www.suse.com/security/cve/CVE-2025-61772","tags":["web"]},{"url":"https://www.suse.com/security/cve/CVE-2025-61919","tags":["web"]},{"url":"https://www.suse.com/security/cve/CVE-2026-22860","tags":["web"]},{"url":"https://www.suse.com/security/cve/CVE-2026-25500","tags":["web"]}],"sources":{"cve":[{"id":"CVE-2026-25500","title":"Rack's Stored XSS in Rack::Directory via javascript: filenames rendered into anchor href","description":"Rack is a modular Ruby web server interface. Prior to versions 2.2.22, 3.1.20, and 3.2.5, `Rack::Directory` generates an HTML directory index where each file entry is rendered as a clickable link. If a file exists on disk whose basename starts with the `javascript:` scheme (e.g. `javascript:alert(1)`), the generated index contains an anchor whose `href` is exactly `javascript:alert(1)`. Clicking the entry executes JavaScript in the browser (demonstrated with `alert(1)`). Versions 2.2.22, 3.1.20, and 3.2.5 fix the issue.","status":"published","published":"2026-02-18T18:59:31.964Z","modified":"2026-02-18T19:42:35.101Z","cvss":[{"version":"3.1","score":5.4,"vector":"CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:C/C:L/I:L/A:N","level":"medium","assessor":"cna"}],"cwes":["CWE-79"],"updated_at":"2026-11-02T13:41:19.694734Z"}],"euvd":[{"id":"EUVD-2026-7916","description":"Rack is a modular Ruby web server interface. Prior to versions 2.2.22, 3.1.20, and 3.2.5, `Rack::Directory` generates an HTML directory index where each file entry is rendered as a clickable link. If a file exists on disk whose basename starts with the `javascript:` scheme (e.g. `javascript:alert(1)`), the generated index contains an anchor whose `href` is exactly `javascript:alert(1)`. Clicking the entry executes JavaScript in the browser (demonstrated with `alert(1)`). Versions 2.2.22, 3.1.20, and 3.2.5 fix the issue.","status":"published","published":"2026-02-18T18:59:31Z","modified":"2026-02-18T19:42:35Z","cvss":[{"version":"3.1","score":5.4,"vector":"CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:C/C:L/I:L/A:N","level":"medium"}],"updated_at":"2026-11-02T19:48:37.43406Z"}],"ghsa":[{"id":"GHSA-whrj-4476-wvmp","title":"Stored XSS in Rack::Directory via javascript: filenames rendered into anchor href","description":"## Summary\n\n`Rack::Directory` generates an HTML directory index where each file entry is rendered as a clickable link. If a file exists on disk whose basename begins with the `javascript:` scheme (e.g. `javascript:alert(1)`), the generated index includes an anchor whose `href` attribute is exactly `javascript:alert(1)`. Clicking this entry executes arbitrary JavaScript in the context of the hosting application.\n\nThis results in a client-side XSS condition in directory listings generated by `Rack::Directory`.\n\n## Details\n\n`Rack::Directory` renders directory entries using an HTML row template similar to:\n\n```html\n\u003ca href='%s'\u003e%s\u003c/a\u003e\n```\n\nThe `%s` placeholder is populated directly with the file’s basename. If the basename begins with `javascript:`, the resulting HTML contains an executable JavaScript URL:\n\n```html\n\u003ca href='javascript:alert(1)'\u003ejavascript:alert(1)\u003c/a\u003e\n```\n\nBecause the value is inserted directly into the `href` attribute without scheme validation or normalization, browsers interpret it as a JavaScript URI. When a user clicks the link, the JavaScript executes in the origin of the Rack application.\n\n## Impact\n\nIf `Rack::Directory` is used to expose filesystem contents over HTTP, an attacker who can create or upload files within that directory may introduce a malicious filename beginning with `javascript:`.\n\nWhen a user visits the directory listing and clicks the entry, arbitrary JavaScript executes in the application's origin. Exploitation requires user interaction (clicking the malicious entry).\n\n## Mitigation\n\n* Update to a patched version of Rack in which `Rack::Directory` prefixes generated anchors with a relative path indicator (e.g. `./filename`).\n* Avoid exposing user-controlled directories via `Rack::Directory`.\n* Apply a strict Content Security Policy (CSP) to reduce impact of potential client-side execution issues.\n* Where feasible, restrict or sanitize uploaded filenames to disallow dangerous URI scheme prefixes.\n\nHackerOne profile:\nhttps://hackerone.com/thesmartshadow\n\nGitHub account owner:\nAli Firas (@thesmartshadow)","status":"published","published":"2026-02-17T18:46:35Z","modified":"2026-03-10T18:41:34Z","cvss":[{"version":"3.1","score":5.4,"vector":"CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:C/C:L/I:L/A:N","level":"medium"}],"cwes":["CWE-79"],"updated_at":"2026-11-02T14:39:33.538417Z"}],"nvd":[{"id":"CVE-2026-25500","description":"Rack is a modular Ruby web server interface. Prior to versions 2.2.22, 3.1.20, and 3.2.5, `Rack::Directory` generates an HTML directory index where each file entry is rendered as a clickable link. If a file exists on disk whose basename starts with the `javascript:` scheme (e.g. `javascript:alert(1)`), the generated index contains an anchor whose `href` is exactly `javascript:alert(1)`. Clicking the entry executes JavaScript in the browser (demonstrated with `alert(1)`). Versions 2.2.22, 3.1.20, and 3.2.5 fix the issue.","status":"published","published":"2026-02-18T20:18:36.11Z","modified":"2026-06-17T10:24:44.857Z","cvss":[{"version":"3.1","score":5.4,"vector":"CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:C/C:L/I:L/A:N","level":"medium","assessor":"secondary"}],"cwes":["CWE-79"],"updated_at":"2026-11-02T14:12:06.274729Z"}],"osv":[{"id":"CVE-2026-25500","title":"Rack's Stored XSS in Rack::Directory via javascript: filenames rendered into anchor href","description":"Rack is a modular Ruby web server interface. Prior to versions 2.2.22, 3.1.20, and 3.2.5, `Rack::Directory` generates an HTML directory index where each file entry is rendered as a clickable link. If a file exists on disk whose basename starts with the `javascript:` scheme (e.g. `javascript:alert(1)`), the generated index contains an anchor whose `href` is exactly `javascript:alert(1)`. Clicking the entry executes JavaScript in the browser (demonstrated with `alert(1)`). Versions 2.2.22, 3.1.20, and 3.2.5 fix the issue.","status":"published","published":"2026-02-18T18:59:31.964Z","modified":"2026-11-11T10:31:06.205502887Z","cvss":[{"version":"3.1","score":5.4,"vector":"CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:C/C:L/I:L/A:N","level":"medium"}],"cwes":["CWE-79"],"updated_at":"2026-11-11T11:06:42.68927Z"},{"id":"DEBIAN-CVE-2026-25500","description":"Rack is a modular Ruby web server interface. Prior to versions 2.2.22, 3.1.20, and 3.2.5, `Rack::Directory` generates an HTML directory index where each file entry is rendered as a clickable link. If a file exists on disk whose basename starts with the `javascript:` scheme (e.g. `javascript:alert(1)`), the generated index contains an anchor whose `href` is exactly `javascript:alert(1)`. Clicking the entry executes JavaScript in the browser (demonstrated with `alert(1)`). Versions 2.2.22, 3.1.20, and 3.2.5 fix the issue.","status":"published","published":"2026-02-18T20:18:36.11Z","modified":"2026-10-01T03:03:00.778243704Z","cvss":[{"version":"3.1","score":5.4,"vector":"CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:C/C:L/I:L/A:N","level":"medium"}],"updated_at":"2026-11-02T15:45:53.877573Z"},{"id":"GHSA-whrj-4476-wvmp","title":"Stored XSS in Rack::Directory via javascript: filenames rendered into anchor href","description":"## Summary\n\n`Rack::Directory` generates an HTML directory index where each file entry is rendered as a clickable link. If a file exists on disk whose basename begins with the `javascript:` scheme (e.g. `javascript:alert(1)`), the generated index includes an anchor whose `href` attribute is exactly `javascript:alert(1)`. Clicking this entry executes arbitrary JavaScript in the context of the hosting application.\n\nThis results in a client-side XSS condition in directory listings generated by `Rack::Directory`.\n\n## Details\n\n`Rack::Directory` renders directory entries using an HTML row template similar to:\n\n```html\n\u003ca href='%s'\u003e%s\u003c/a\u003e\n```\n\nThe `%s` placeholder is populated directly with the file’s basename. If the basename begins with `javascript:`, the resulting HTML contains an executable JavaScript URL:\n\n```html\n\u003ca href='javascript:alert(1)'\u003ejavascript:alert(1)\u003c/a\u003e\n```\n\nBecause the value is inserted directly into the `href` attribute without scheme validation or normalization, browsers interpret it as a JavaScript URI. When a user clicks the link, the JavaScript executes in the origin of the Rack application.\n\n## Impact\n\nIf `Rack::Directory` is used to expose filesystem contents over HTTP, an attacker who can create or upload files within that directory may introduce a malicious filename beginning with `javascript:`.\n\nWhen a user visits the directory listing and clicks the entry, arbitrary JavaScript executes in the application's origin. Exploitation requires user interaction (clicking the malicious entry).\n\n## Mitigation\n\n* Update to a patched version of Rack in which `Rack::Directory` prefixes generated anchors with a relative path indicator (e.g. `./filename`).\n* Avoid exposing user-controlled directories via `Rack::Directory`.\n* Apply a strict Content Security Policy (CSP) to reduce impact of potential client-side execution issues.\n* Where feasible, restrict or sanitize uploaded filenames to disallow dangerous URI scheme prefixes.\n\nHackerOne profile:\nhttps://hackerone.com/thesmartshadow\n\nGitHub account owner:\nAli Firas (@thesmartshadow)","status":"published","published":"2026-02-17T18:46:35Z","modified":"2026-09-10T03:50:36.160309045Z","cvss":[{"version":"3.1","score":5.4,"vector":"CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:C/C:L/I:L/A:N","level":"medium"}],"cwes":["CWE-79"],"updated_at":"2026-11-02T15:46:58.767335Z"},{"id":"UBUNTU-CVE-2026-25500","description":"Rack is a modular Ruby web server interface. Prior to versions 2.2.22, 3.1.20, and 3.2.5, `Rack::Directory` generates an HTML directory index where each file entry is rendered as a clickable link. If a file exists on disk whose basename starts with the `javascript:` scheme (e.g. `javascript:alert(1)`), the generated index contains an anchor whose `href` is exactly `javascript:alert(1)`. Clicking the entry executes JavaScript in the browser (demonstrated with `alert(1)`). Versions 2.2.22, 3.1.20, and 3.2.5 fix the issue.","status":"published","published":"2026-02-18T20:18:00Z","modified":"2026-10-17T12:58:07.333323145Z","cvss":[{"version":"3.1","score":5.4,"vector":"CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:C/C:L/I:L/A:N","level":"medium"}],"updated_at":"2026-11-02T16:56:08.726452Z"},{"id":"DLA-4505-1","title":"ruby-rack - security update","status":"published","published":"2026-03-23T00:00:00Z","modified":"2026-03-23T00:00:00Z","updated_at":"2026-11-02T15:46:13.207219Z"},{"id":"DSA-6180-1","title":"ruby-rack - security update","status":"published","published":"2026-03-26T00:00:00Z","modified":"2026-03-26T22:31:23.149907Z","updated_at":"2026-11-02T15:46:18.296714Z"},{"id":"MGASA-2026-0075","title":"Updated ruby-rack packages fix security vulnerabilities","description":"Rack has a Directory Traversal via Rack:Directory. (CVE-2026-22860)\nRack's Stored XSS in Rack::Directory via javascript: filenames rendered\ninto anchor href. (CVE-2026-25500)\n","status":"published","published":"2026-03-31T23:05:51Z","modified":"2026-04-16T04:43:22.408165615Z","updated_at":"2026-11-02T15:49:43.178336Z"},{"id":"openSUSE-SU-2026:10286-1","title":"ruby4.0-rubygem-rack-2.2-2.2.22-1.1 on GA media","description":"These are all security issues fixed in the ruby4.0-rubygem-rack-2.2-2.2.22-1.1 package on the GA media of openSUSE Tumbleweed.","status":"published","published":"2026-03-04T00:00:00Z","modified":"2026-03-23T04:54:39.054152Z","updated_at":"2026-11-02T16:58:38.101535Z"}]}}
