Local File Inclusion in Rack::Static
Description
Rack provides an interface for developing web applications in Ruby. Prior to versions 2.2.13, 3.0.14, and 3.1.12, Rack::Static can serve files under the specified root: even if urls: are provided, which may expose other files under the specified root: unexpectedly. The vulnerability occurs because Rack::Static does not properly sanitize user-supplied paths before serving files. Specifically, encoded path traversal sequences are not correctly validated, allowing attackers to access files outside the designated static file directory. By exploiting this vulnerability, an attacker can gain access to all files under the specified root: directory, provided they are able to determine then path of the file. Versions 2.2.13, 3.0.14, and 3.1.12 contain a patch for the issue. Other mitigations include removing usage of Rack::Static, or ensuring that root: points at a directory path which only contains files which should be accessed publicly. It is likely that a CDN or similar static file server would also mitigate the issue.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
rackRubyGems | < 2.2.13 | 2.2.13 |
rackRubyGems | >= 3.0, < 3.0.14 | 3.0.14 |
rackRubyGems | >= 3.1, < 3.1.12 | 3.1.12 |
Affected products
1Patches
150caab74fa01Use a fully resolved file path when confirming if a file can be served by `Rack::Static`.
2 files changed · +8 −1
lib/rack/static.rb+2 −1 modified@@ -124,8 +124,9 @@ def can_serve(path) def call(env) path = env[PATH_INFO] + actual_path = Utils.clean_path_info(Utils.unescape_path(path)) - if can_serve(path) + if can_serve(actual_path) if overwrite_file_path(path) env[PATH_INFO] = (add_index_root?(path) ? path + @index : @urls[path]) elsif @gzip && env['HTTP_ACCEPT_ENCODING'] && /\bgzip\b/.match?(env['HTTP_ACCEPT_ENCODING'])
test/spec_static.rb+6 −0 modified@@ -49,6 +49,12 @@ def static(app, *args) res.body.must_match(/ruby/) end + it "does not serve files outside :urls" do + res = @request.get("/cgi/../#{File.basename(__FILE__)}") + res.must_be :ok? + res.body.must_equal "Hello World" + end + it "404s if url root is known but it can't find the file" do res = @request.get("/cgi/foo") res.must_be :not_found?
Vulnerability mechanics
Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
6- github.com/advisories/GHSA-7wqh-767x-r66vghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2025-27610ghsaADVISORY
- github.com/rack/rack/commit/50caab74fa01ee8f5dbdee7bb2782126d20c6583ghsax_refsource_MISCWEB
- github.com/rack/rack/security/advisories/GHSA-7wqh-767x-r66vghsax_refsource_CONFIRMWEB
- github.com/rubysec/ruby-advisory-db/blob/master/gems/rack/CVE-2025-27610.ymlghsaWEB
- lists.debian.org/debian-lts-announce/2025/03/msg00016.htmlghsaWEB
News mentions
0No linked articles in our index yet.