CVE-2026-25500
Rack's Stored XSS in Rack::Directory via javascript: filenames rendered into anchor href
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.
Attack profile
How easy it is to exploit
- Attack vector
- Network
- Complexity
- Low
- Privileges needed
- Low
- User interaction
- Required
What an attacker can affect
- Confidentiality
- Low
- Integrity
- Low
- Availability
- None
Exploit likelihood
What each source reports
CVE List Score used
5.4
Rack's Stored XSS in Rack::Directory via javascript: filenames rendered into anchor href
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.
- Record
CVE-2026-25500- CVSS 3.1
- 5.4 Medium
CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:C/C:L/I:L/A:N - Weakness
- CWE-79
- Updated
- 2026-11-02
EUVDEUVD-2026-7916
5.4
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.
- Record
EUVD-2026-7916- CVSS 3.1
- 5.4 Medium
CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:C/C:L/I:L/A:N - Updated
- 2026-11-02
GitHub AdvisoriesGHSA-whrj-4476-wvmp
5.4
Stored XSS in Rack::Directory via javascript: filenames rendered into anchor href
Summary
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.
This results in a client-side XSS condition in directory listings generated by Rack::Directory.
Details
Rack::Directory renders directory entries using an HTML row template similar to:
<a href='%s'>%s</a>
The %s placeholder is populated directly with the file’s basename. If the basename begins with javascript:, the resulting HTML contains an executable JavaScript URL:
<a href='javascript:alert(1)'>javascript:alert(1)</a>
Because 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.
Impact
If 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:.
When 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).
Mitigation
- Update to a patched version of Rack in which
Rack::Directoryprefixes generated anchors with a relative path indicator (e.g../filename). - Avoid exposing user-controlled directories via
Rack::Directory. - Apply a strict Content Security Policy (CSP) to reduce impact of potential client-side execution issues.
- Where feasible, restrict or sanitize uploaded filenames to disallow dangerous URI scheme prefixes.
HackerOne profile: https://hackerone.com/thesmartshadow
GitHub account owner: Ali Firas (@thesmartshadow)
- Record
GHSA-whrj-4476-wvmp- CVSS 3.1
- 5.4 Medium
CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:C/C:L/I:L/A:N - Weakness
- CWE-79
- Updated
- 2026-11-02
NVD
5.4
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.
- Record
CVE-2026-25500- CVSS 3.1
- 5.4 Medium
CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:C/C:L/I:L/A:N - Weakness
- CWE-79
- Updated
- 2026-11-02
OSV
5.4
Rack's Stored XSS in Rack::Directory via javascript: filenames rendered into anchor href
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.
- Record
CVE-2026-25500- CVSS 3.1
- 5.4 Medium
CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:C/C:L/I:L/A:N - Weakness
- CWE-79
- Updated
- 2026-11-02
OSVDEBIAN-CVE-2026-25500
5.4
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.
- Record
DEBIAN-CVE-2026-25500- CVSS 3.1
- 5.4 Medium
CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:C/C:L/I:L/A:N - Updated
- 2026-11-02
Show 4 moreShow less
OSVGHSA-whrj-4476-wvmp
5.4
Stored XSS in Rack::Directory via javascript: filenames rendered into anchor href
Summary
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.
This results in a client-side XSS condition in directory listings generated by Rack::Directory.
Details
Rack::Directory renders directory entries using an HTML row template similar to:
<a href='%s'>%s</a>
The %s placeholder is populated directly with the file’s basename. If the basename begins with javascript:, the resulting HTML contains an executable JavaScript URL:
<a href='javascript:alert(1)'>javascript:alert(1)</a>
Because 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.
Impact
If 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:.
When 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).
Mitigation
- Update to a patched version of Rack in which
Rack::Directoryprefixes generated anchors with a relative path indicator (e.g../filename). - Avoid exposing user-controlled directories via
Rack::Directory. - Apply a strict Content Security Policy (CSP) to reduce impact of potential client-side execution issues.
- Where feasible, restrict or sanitize uploaded filenames to disallow dangerous URI scheme prefixes.
HackerOne profile: https://hackerone.com/thesmartshadow
GitHub account owner: Ali Firas (@thesmartshadow)
- Record
GHSA-whrj-4476-wvmp- CVSS 3.1
- 5.4 Medium
CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:C/C:L/I:L/A:N - Weakness
- CWE-79
- Updated
- 2026-11-02
OSVUBUNTU-CVE-2026-25500
5.4
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.
- Record
UBUNTU-CVE-2026-25500- CVSS 3.1
- 5.4 Medium
CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:C/C:L/I:L/A:N - Updated
- 2026-11-02
OSVMGASA-2026-0075 No score
Updated ruby-rack packages fix security vulnerabilities
Rack has a Directory Traversal via Rack:Directory. (CVE-2026-22860) Rack's Stored XSS in Rack::Directory via javascript: filenames rendered into anchor href. (CVE-2026-25500)
- Record
MGASA-2026-0075- Updated
- 2026-11-02
OSVopenSUSE-SU-2026:10286-1 No score
ruby4.0-rubygem-rack-2.2-2.2.22-1.1 on GA media
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.
- Record
openSUSE-SU-2026:10286-1- Updated
- 2026-11-02
Affected products
Affected packages
| Package | Affected | Fixed |
|---|---|---|
rackRubyGems |
before 2.2.22 | 2.2.22 |
rackRubyGems |
3.0.0.beta1 up to 3.1.20 | 3.1.20 |
rackRubyGems |
3.2.0 up to 3.2.5 | 3.2.5 |
ruby-rackDebian:12 |
before 2.2.22-0+deb12u1, plus listed versions 2.2.13-1~deb12u12.2.20-0+deb12u12.2.6.4-12.2.6.4-1+deb12u12.2.7-12.2.7-1.1 |
2.2.22-0+deb12u1 |
ruby-rackDebian:13 |
before 3.1.20-0+deb13u1, plus listed versions 3.1.16-0.13.1.18-13.1.18-1~deb13u1 |
3.1.20-0+deb13u1 |
ruby-rackDebian:14 |
before 3.2.5-1, plus listed versions 3.1.16-0.13.1.18-13.1.18-1~deb13u13.2.4-1 |
3.2.5-1 |
ruby-rackDebian:11 From an advisory covering 2 CVEs |
before 2.1.4-3+deb11u5, plus listed versions 2.1.4-32.1.4-3+deb11u12.1.4-3+deb11u22.1.4-3+deb11u32.1.4-3+deb11u4 |
2.1.4-3+deb11u5 |
ruby-rackDebian:12 From an advisory covering 2 CVEs |
before 2.2.22-0+deb12u1, plus listed versions 2.2.13-1~deb12u12.2.20-0+deb12u12.2.6.4-12.2.6.4-1+deb12u12.2.7-12.2.7-1.1 |
2.2.22-0+deb12u1 |
ruby-rackDebian:13 From an advisory covering 2 CVEs |
before 3.1.20-0+deb13u1, plus listed versions 3.1.16-0.13.1.18-13.1.18-1~deb13u1 |
3.1.20-0+deb13u1 |
rackRubyGems |
before 2.2.22, plus listed versions 0.1.00.2.00.3.00.4.00.9.0 Show 45 moreShow less0.9.11.0.01.0.11.1.01.1.11.1.1.pre1.1.21.1.31.1.41.1.51.1.61.2.01.2.11.2.21.2.31.2.41.2.51.2.61.2.71.2.81.3.01.3.0.beta1.3.0.beta21.3.11.3.101.3.21.3.31.3.41.3.51.3.61.3.71.3.81.3.91.4.01.4.11.4.21.4.31.4.41.4.51.4.61.4.71.5.01.5.0.beta.11.5.0.beta.21.5.1 |
2.2.22 |
Show 13 moreShow less
| Package | Affected | Fixed |
|---|---|---|
rackRubyGems |
3.0.0.beta1 up to 3.1.20, plus listed versions 3.0.03.0.0.rc13.0.13.0.103.0.11 Show 39 moreShow less3.0.123.0.133.0.143.0.153.0.163.0.173.0.183.0.23.0.33.0.43.0.4.13.0.4.23.0.53.0.63.0.6.13.0.73.0.83.0.93.0.9.13.1.03.1.13.1.103.1.113.1.123.1.133.1.143.1.153.1.163.1.173.1.183.1.193.1.23.1.33.1.43.1.53.1.63.1.73.1.83.1.9 |
3.1.20 |
rackRubyGems |
3.2.0 up to 3.2.5, plus listed versions 3.2.13.2.23.2.33.2.4 |
3.2.5 |
ruby-rackMageia:9 From an advisory covering 2 CVEs |
before 2.2.22-1.mga9 | 2.2.22-1.mga9 |
ruby-rackUbuntu:Pro:14.04:LTS |
All versions, plus listed versions 1.5.2-11.5.2-1ubuntu0.1~esm11.5.2-3+deb8u3ubuntu1~esm21.5.2-3+deb8u3ubuntu1~esm31.5.2-3+deb8u3ubuntu1~esm4 Show 6 moreShow less1.5.2-3+deb8u3ubuntu1~esm61.5.2-3+deb8u3ubuntu1~esm71.5.2-3+deb8u3ubuntu1~esm81.5.2-3+deb8u3ubuntu1~esm91.5.2-3+deb8u3ubuntu1~esm101.5.2-3+deb8u3ubuntu1~esm11 |
None known |
ruby-rackUbuntu:Pro:16.04:LTS |
All versions, plus listed versions 1.5.2-41.6.4-21.6.4-31.6.4-3ubuntu0.11.6.4-3ubuntu0.2 Show 9 moreShow less1.6.4-3ubuntu0.2+esm11.6.4-3ubuntu0.2+esm21.6.4-3ubuntu0.2+esm41.6.4-3ubuntu0.2+esm51.6.4-3ubuntu0.2+esm61.6.4-3ubuntu0.2+esm71.6.4-3ubuntu0.2+esm81.6.4-3ubuntu0.2+esm91.6.4-3ubuntu0.2+esm10 |
None known |
ruby-rackUbuntu:Pro:18.04:LTS |
All versions, plus listed versions 1.6.4-41.6.4-4ubuntu0.11.6.4-4ubuntu0.21.6.4-4ubuntu0.2+esm11.6.4-4ubuntu0.2+esm2 Show 7 moreShow less1.6.4-4ubuntu0.2+esm41.6.4-4ubuntu0.2+esm51.6.4-4ubuntu0.2+esm61.6.4-4ubuntu0.2+esm71.6.4-4ubuntu0.2+esm81.6.4-4ubuntu0.2+esm91.6.4-4ubuntu0.2+esm10 |
None known |
ruby-rackUbuntu:Pro:20.04:LTS |
before 2.0.7-2ubuntu0.1+esm9, plus listed versions 2.0.6-32.0.7-22.0.7-2ubuntu0.12.0.7-2ubuntu0.1+esm12.0.7-2ubuntu0.1+esm2 Show 6 moreShow less2.0.7-2ubuntu0.1+esm32.0.7-2ubuntu0.1+esm42.0.7-2ubuntu0.1+esm52.0.7-2ubuntu0.1+esm62.0.7-2ubuntu0.1+esm72.0.7-2ubuntu0.1+esm8 |
2.0.7-2ubuntu0.1+esm9 |
ruby-rackUbuntu:Pro:22.04:LTS |
before 2.1.4-5ubuntu1.2+esm2, plus listed versions 2.1.4-32.1.4-42.1.4-52.1.4-5ubuntu12.1.4-5ubuntu1+esm2 Show 8 moreShow less2.1.4-5ubuntu1+esm32.1.4-5ubuntu1+esm42.1.4-5ubuntu1+esm52.1.4-5ubuntu1.12.1.4-5ubuntu1.1+esm12.1.4-5ubuntu1.1+esm22.1.4-5ubuntu1.22.1.4-5ubuntu1.2+esm1 |
2.1.4-5ubuntu1.2+esm2 |
ruby-rackUbuntu:24.04:LTS |
before 2.2.7-1ubuntu0.6, plus listed versions 2.2.4-32.2.7-12.2.7-1ubuntu0.12.2.7-1ubuntu0.22.2.7-1ubuntu0.32.2.7-1ubuntu0.42.2.7-1ubuntu0.5 |
2.2.7-1ubuntu0.6 |
ruby-rackUbuntu:25.10 |
before 3.1.16-0.1ubuntu0.2, plus listed versions 2.2.7-1.13.1.16-0.13.1.16-0.1ubuntu0.1 |
3.1.16-0.1ubuntu0.2 |
ruby-rackUbuntu:26.10 |
before 3.2.4-1ubuntu1 | 3.2.4-1ubuntu1 |
ruby-rackUbuntu:26.04:LTS |
before 3.2.4-1ubuntu1, plus listed versions 3.1.16-0.13.1.18-13.1.18-1build1 |
3.2.4-1ubuntu1 |
rubygem-rack-2.2openSUSE:Tumbleweed From an advisory covering 27 CVEs |
before 2.2.22-1.1 | 2.2.22-1.1 |
History
| Recorded | Changed | Sources |
|---|---|---|
| affected, facts | ||
| first indexed | CVE List, EUVD, GitHub Advisories, NVD, OSV |
Dates are when Every CVE recorded each change. Upstream dates may differ.
In short
CVE-2026-25500 is a medium vulnerability (CVSS 5.4) in Rack, published February 17, 2026. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.27%, the 19th percentile. Fixed in rack 2.2.22.
References
github.com/rack/rack/security/advisories/GHSA-whrj-4476-wvmp
github.com/rack/rack/commit/f2f225f297b99fbee3d9f51255d41f601fc40aff
nvd.nist.gov/vuln/detail/CVE-2026-25500
github.com/rubysec/ruby-advisory-db/blob/master/gems/rack/CVE-2026-25500.yml
github.com/advisories/GHSA-whrj-4476-wvmp
github.com/CVEProject/cvelistV5/tree/main/cves/2026/25xxx/CVE-2026-25500.json
Show 35 moreShow less
security-tracker.debian.org/tracker/CVE-2026-25500
github.com/rack/rack
advisories.mageia.org/MGASA-2026-0075.html
bugs.mageia.org/show_bug.cgi?id=35285
lists.debian.org/debian-security-announce/2026/msg00089.html
ubuntu.com/security/CVE-2026-25500
cve.org/CVERecord?id=CVE-2026-25500
ubuntu.com/security/notices/USN-8066-1
suse.com/security/cve/CVE-2013-0262
suse.com/security/cve/CVE-2013-0263
suse.com/security/cve/CVE-2015-3225
suse.com/security/cve/CVE-2018-16471
suse.com/security/cve/CVE-2019-16782
suse.com/security/cve/CVE-2020-8184
suse.com/security/cve/CVE-2022-30122
suse.com/security/cve/CVE-2022-30123
suse.com/security/cve/CVE-2022-44570
suse.com/security/cve/CVE-2022-44571
suse.com/security/cve/CVE-2022-44572
suse.com/security/cve/CVE-2023-27530
suse.com/security/cve/CVE-2023-27539
suse.com/security/cve/CVE-2024-25126
suse.com/security/cve/CVE-2024-26141
suse.com/security/cve/CVE-2024-26146
suse.com/security/cve/CVE-2025-25184
suse.com/security/cve/CVE-2025-27111
suse.com/security/cve/CVE-2025-27610
suse.com/security/cve/CVE-2025-46727
suse.com/security/cve/CVE-2025-59830
suse.com/security/cve/CVE-2025-61770
suse.com/security/cve/CVE-2025-61771
suse.com/security/cve/CVE-2025-61772
suse.com/security/cve/CVE-2025-61919
suse.com/security/cve/CVE-2026-22860
suse.com/security/cve/CVE-2026-25500
Left out here: 72 versions. The JSON record has them.