Cloudanix VulnDB

CVE-2025-27610

None

CVSS

—

EPSS

1.2%

Published

Mar 10, 2025

CISA due date

—

Cloudanix analysis

Next patch cycle SSVC: Track

Some Ruby web applications may accidentally let outsiders download private files if static file serving is configured unsafely.

Exploitation
Remote Unauthenticated
Attacker needs
None
Complexity
Low
Impact
Data Exposure
Component
Web Framework
Class
Path Traversal
Remediation
Upgrade
Effort
Medium
Patch risk
Low

What it actually does

This is a path traversal flaw in Rack::Static, the Rack middleware commonly used by Ruby web applications to serve static files. In affected Rack versions before 2.2.13, 3.0.14, and 3.1.12, encoded traversal sequences in user-supplied request paths are not validated correctly. As a result, an attacker can bypass the intended urls: restriction and cause Rack::Static to serve other files located under the configured root: directory. The practical impact depends on how root: is configured: if it points only to a public static directory, exposure may be limited; if it points to an application root or broad filesystem location, sensitive application files, configuration files, dependency manifests, or secrets may be exposed.

Why it matters to the business

Successful exploitation can lead to unauthorized disclosure of files that were never intended to be publicly accessible. Exposed configuration files may reveal credentials, secret keys, service endpoints, deployment details, or application internals that enable follow-on attacks. The risk is most significant for Ruby applications that use Rack::Static with root: set to an application directory or any directory containing non-public files. The issue is not currently listed in CISA KEV, has low EPSS, and no public exploit maturity is indicated, but it has been public for a long time and is straightforward to test remotely when the vulnerable middleware is exposed.

How an attack unfolds

An attacker first identifies a Ruby/Rack-based web application serving static content through Rack::Static. They then probe static URL paths with encoded path traversal sequences that may be decoded by Rack in a way that bypasses the configured urls: allowlist or prefix restriction. If the application is vulnerable and the requested target file exists under the configured root: directory, Rack::Static returns that file in the HTTP response. The attacker repeats this process using guessed filenames common to Ruby applications, such as dependency files, Rack configuration, environment files, or framework configuration files. Any disclosed secrets or operational details can then be used for credential theft, source code reconnaissance, cloud/service access attempts, or more targeted application exploitation.

How to fix it

Upgrade Rack to a fixed release: 2.2.13 or later for the 2.2 branch, 3.0.14 or later for the 3.0 branch, or 3.1.12 or later for the 3.1 branch. For source-based consumers, ensure the fix including commit df6c47357f6c6bec2d585f45f417285d813d9b3a is present. Rebuild and redeploy all affected applications and container images that package vulnerable Rack versions. If immediate upgrade is not possible, remove Rack::Static usage where feasible, serve static content through a dedicated web server/CDN/object storage layer, or ensure Rack::Static root: points only to a directory containing files that are intentionally public. Do not configure root: to the application root, repository root, home directory, or any directory containing secrets or configuration files. Add WAF or reverse-proxy rules to block encoded traversal patterns as a compensating control, but do not treat filtering as a substitute for upgrading.

How to confirm the fix worked

Confirm the installed Rack version in dependency manifests and runtime artifacts, such as Gemfile.lock, gem inventory, container SBOMs, and deployed application images. Validate that Rack resolves to 2.2.13, 3.0.14, 3.1.12, or a later fixed version. Review application configuration for Rack::Static usage and verify that root: points only to a deliberately public static-file directory. After patching or reconfiguration, send safe negative tests for encoded traversal attempts against static URL paths and confirm the application returns 403, 404, or equivalent denial responses rather than file contents. Also verify that sensitive files such as application config, dependency manifests, and environment files are not reachable through any static URL route.

Typical attack path

  1. Identify a Rack or Ruby web application that serves static files directly through Rack::Static.
  2. Enumerate likely static URL prefixes and observe response behavior for normal static assets.
  3. Send requests containing URL-encoded path traversal sequences such as encoded ../ components.
  4. Attempt to retrieve predictable files under the configured Rack::Static root directory.
  5. Review successful HTTP 200/206 responses for sensitive configuration, credentials, secrets, or application internals.
  6. Use any disclosed information to support follow-on attacks such as credential abuse, source-code-informed exploitation, or lateral movement into connected services.

How to detect it

Review historical web server, reverse proxy, CDN, WAF, load balancer, and application access logs for requests to static routes containing encoded traversal sequences. Pay particular attention to requests with %2e, %2f, %5c, double-encoded traversal strings, or unusual attempts to access Ruby application files. Successful exploitation is most likely indicated by HTTP 200, 206, or unusually large 304 responses for filenames that should not be public, such as Gemfile, Gemfile.lock, config.ru, .env, config/database.yml, config/secrets.yml, config/master.key, or credentials files. Look for probing patterns where one source repeatedly requests many guessed filenames and receives a mix of 404 and successful responses. If EDR, file access auditing, or application instrumentation is available, correlate suspicious HTTP requests with the web application process reading sensitive files under the Rack::Static root directory. If any sensitive configuration or secret-bearing file was served, treat associated credentials and keys as potentially compromised.

  • %2e%2e%2f
  • %2e%2e/
  • ..%2f
  • %2e%2e%5c
  • ..%5c
  • %252e%252e%252f
  • %252e%252e%255c
  • /%2e%2e%2fGemfile
  • /%2e%2e%2fGemfile.lock
  • /%2e%2e%2fconfig.ru
  • /%2e%2e%2f.env
  • /%2e%2e%2fconfig%2fdatabase.yml
  • /%2e%2e%2fconfig%2fsecrets.yml
  • /%2e%2e%2fconfig%2fmaster.key
  • /%2e%2e%2fconfig%2fcredentials.yml.enc
  • /%252e%252e%252fGemfile
  • /%252e%252e%252f.env
  • GET /assets/%2e%2e%2f
  • GET /static/%2e%2e%2f
  • GET /public/%2e%2e%2f
  • GET /packs/%2e%2e%2f

What your security team should do

  • Inventory Ruby applications and services that depend on Rack and prioritize any internet-facing systems using Rack::Static.
  • Upgrade Rack to 2.2.13, 3.0.14, 3.1.12, or later fixed versions, and rebuild/deploy affected images or packages.
  • Search code and configuration for Rack::Static usage, especially configurations where root: is set to an application root or broad directory.
  • Move static file serving to a CDN, reverse proxy, object storage bucket, or dedicated public directory where possible.
  • Add temporary WAF/reverse-proxy detections and blocks for encoded path traversal sequences targeting static paths.
  • Review historical access logs for traversal probes and successful responses serving sensitive Ruby or application configuration files.
  • If sensitive files may have been exposed, rotate affected secrets and investigate downstream use of disclosed credentials.

The record

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

Ecosystem Package Introduced Fixed
RubyGems rack 0 2.2.13
RubyGems rack 3.0 3.0.14
RubyGems rack 3.1 3.1.12
Chainguard gitaly-config-17.8 0 17.8.4-r31
Chainguard gitaly-config-17.9 0 17.9.2-r2
Chainguard gitlab-base-17.8 0 17.8.4-r31
Chainguard gitlab-base-17.9 0 17.9.2-r2
Chainguard gitlab-certificates-17.8 0 17.8.4-r31
Chainguard gitlab-certificates-17.9 0 17.9.2-r2
Chainguard gitlab-cfssl-self-sign-scripts-17.8 0 17.8.4-r31
Chainguard gitlab-cfssl-self-sign-scripts-17.9 0 17.9.2-r2
Chainguard gitlab-cng-17.8 0 17.8.4-r31
Chainguard gitlab-cng-17.9 0 17.9.2-r2
Chainguard gitlab-container-registry-17.8 0 17.8.4-r31
Chainguard gitlab-container-registry-17.9 0 17.9.2-r2
Chainguard gitlab-container-registry-compat-17.8 0 17.8.4-r31
Chainguard gitlab-container-registry-compat-17.9 0 17.9.2-r2
Chainguard gitlab-container-registry-scripts-17.8 0 17.8.4-r31
Chainguard gitlab-container-registry-scripts-17.9 0 17.9.2-r2
Chainguard gitlab-elasticsearch-indexer-17.8 0 17.8.4-r31
Chainguard gitlab-elasticsearch-indexer-17.9 0 17.9.2-r2
Chainguard gitlab-elasticsearch-indexer-compat-17.8 0 17.8.4-r31
Chainguard gitlab-elasticsearch-indexer-compat-17.9 0 17.9.2-r2
Chainguard gitlab-exporter-17.8 0 17.8.4-r31
Chainguard gitlab-exporter-17.9 0 17.9.2-r2
Chainguard gitlab-exporter-scripts-17.8 0 17.8.4-r31
Chainguard gitlab-exporter-scripts-17.9 0 17.9.2-r2
Chainguard gitlab-geo-logcursor-scripts-17.8 0 17.8.4-r31
Chainguard gitlab-geo-logcursor-scripts-17.9 0 17.9.2-r2
Chainguard gitlab-gitaly-scripts-17.8 0 17.8.4-r31
Chainguard gitlab-gitaly-scripts-17.9 0 17.9.2-r2
Chainguard gitlab-logger-17.8 0 17.8.4-r31
Chainguard gitlab-logger-17.9 0 17.9.2-r2
Chainguard gitlab-logger-compat-17.8 0 17.8.4-r31
Chainguard gitlab-logger-compat-17.9 0 17.9.2-r2
Chainguard gitlab-mailroom-17.8 0 17.8.4-r31
Chainguard gitlab-mailroom-17.9 0 17.9.2-r2
Chainguard gitlab-mailroom-scripts-17.8 0 17.8.4-r31
Chainguard gitlab-mailroom-scripts-17.9 0 17.9.2-r2
Chainguard gitlab-pages-scripts-17.8 0 17.8.4-r31
Chainguard gitlab-pages-scripts-17.9 0 17.9.2-r2
Chainguard gitlab-rails-scripts-17.8 0 17.8.4-r31
Chainguard gitlab-rails-scripts-17.9 0 17.9.2-r2
Chainguard gitlab-shell-17.8 0 17.8.4-r31
Chainguard gitlab-shell-17.9 0 17.9.2-r2
Chainguard gitlab-shell-scripts-17.8 0 17.8.4-r31
Chainguard gitlab-shell-scripts-17.9 0 17.9.2-r2
Chainguard gitlab-shell-scripts-compat-17.8 0 17.8.4-r31
Chainguard gitlab-shell-scripts-compat-17.9 0 17.9.2-r2
Chainguard gitlab-sidekiq-scripts-17.8 0 17.8.4-r31
Chainguard gitlab-sidekiq-scripts-17.9 0 17.9.2-r2
Chainguard gitlab-toolbox-scripts-17.8 0 17.8.4-r31
Chainguard gitlab-toolbox-scripts-17.9 0 17.9.2-r2
Chainguard gitlab-webservice-config-17.8 0 17.8.4-r31
Chainguard gitlab-webservice-config-17.9 0 17.9.2-r2
Chainguard gitlab-webservice-scripts-17.8 0 17.8.4-r31
Chainguard gitlab-webservice-scripts-17.9 0 17.9.2-r2
Chainguard gitlab-workhorse-scripts-17.8 0 17.8.4-r31
Chainguard gitlab-workhorse-scripts-17.9 0 17.9.2-r2
Chainguard kube-fluentd-operator 0 1.18.2-r31
Chainguard kube-fluentd-operator-compat 0 1.18.2-r31
Chainguard kube-fluentd-operator-default-config 0 1.18.2-r31
Chainguard kube-fluentd-operator-oci-entrypoint 0 1.18.2-r31
Chainguard logstash-8 0 8.17.3-r2
Chainguard logstash-8-bitnami-compat 0 8.17.3-r2
Chainguard logstash-8-compat 0 8.17.3-r2
Chainguard logstash-8-env2yaml 0 8.17.3-r2
Chainguard logstash-8-iamguarded-compat 0 8.17.3-r2
Chainguard logstash-8-with-output-opensearch 0 8.17.3-r2
Chainguard logstash-jre-bcfips 0 8.17.4-r0
Chainguard logstash-jre-bcfips-compat 0 8.17.4-r0
Chainguard logstash-jre-bcfips-env2yaml 0 8.17.4-r0
Chainguard logstash-jre-bcfips-with-output-opensearch 0 8.17.4-r0
Chainguard ruby3.2-rails-7.1 0 7.1.5.1-r4
Chainguard ruby3.2-rails-7.1-compat 0 7.1.5.1-r4
Chainguard ruby3.2-rails-8.0 0 8.0.2-r0
Chainguard ruby3.2-rails-8.0-compat 0 8.0.2-r0
Chainguard ruby3.3-rack-2.2 0 2.2.22-r0
Chainguard ruby3.3-rails-7.1 0 7.1.5.1-r4
Chainguard ruby3.3-rails-7.1-compat 0 7.1.5.1-r4
Chainguard ruby3.3-rails-7.2 0 7.2.2.1-r4
Chainguard ruby3.3-rails-7.2-compat 0 7.2.2.1-r4
Chainguard ruby3.4-rails-7.1 0 7.1.5.1-r4
Chainguard ruby3.4-rails-7.1-compat 0 7.1.5.1-r4
Chainguard ruby3.4-rails-7.2 0 7.2.2.1-r4
Chainguard ruby3.4-rails-7.2-compat 0 7.2.2.1-r4
Chainguard ruby3.4-rails-8.0 0 8.0.2-r0
Chainguard ruby3.4-rails-8.0-compat 0 8.0.2-r0
Debian:11 ruby-rack 0 No fix
Debian:11 ruby-rack 0 2.1.4-3+deb11u3
Debian:12 ruby-rack 0 No fix
Debian:12 ruby-rack 0 2.2.13-1~deb12u1
Debian:13 ruby-rack 0 No fix
Debian:13 ruby-rack 0 3.1.12-1
Mageia:9 ruby-rack 0 2.2.13-1.mga9
SUSE:Linux Enterprise High Availability Extension 15 SP3 rubygem-rack 0 2.0.8-150000.3.26.1
SUSE:Linux Enterprise High Availability Extension 15 SP4 rubygem-rack 0 2.0.8-150000.3.26.1
SUSE:Linux Enterprise High Availability Extension 15 SP5 rubygem-rack 0 2.0.8-150000.3.26.1
SUSE:Linux Enterprise High Availability Extension 15 SP6 rubygem-rack 0 2.0.8-150000.3.26.1
Wolfi gitaly-config-17.8 0 17.8.4-r31
Wolfi gitaly-config-17.9 0 17.9.2-r2
Wolfi gitlab-base-17.8 0 17.8.4-r31
Wolfi gitlab-base-17.9 0 17.9.2-r2
Wolfi gitlab-certificates-17.8 0 17.8.4-r31
Wolfi gitlab-certificates-17.9 0 17.9.2-r2
Wolfi gitlab-cfssl-self-sign-scripts-17.8 0 17.8.4-r31
Wolfi gitlab-cfssl-self-sign-scripts-17.9 0 17.9.2-r2
Wolfi gitlab-cng-17.8 0 17.8.4-r31
Wolfi gitlab-cng-17.9 0 17.9.2-r2
Wolfi gitlab-container-registry-17.8 0 17.8.4-r31
Wolfi gitlab-container-registry-17.9 0 17.9.2-r2
Wolfi gitlab-container-registry-compat-17.8 0 17.8.4-r31
Wolfi gitlab-container-registry-compat-17.9 0 17.9.2-r2
Wolfi gitlab-container-registry-scripts-17.8 0 17.8.4-r31
Wolfi gitlab-container-registry-scripts-17.9 0 17.9.2-r2
Wolfi gitlab-elasticsearch-indexer-17.8 0 17.8.4-r31
Wolfi gitlab-elasticsearch-indexer-17.9 0 17.9.2-r2
Wolfi gitlab-elasticsearch-indexer-compat-17.8 0 17.8.4-r31
Wolfi gitlab-elasticsearch-indexer-compat-17.9 0 17.9.2-r2
Wolfi gitlab-exporter-17.8 0 17.8.4-r31
Wolfi gitlab-exporter-17.9 0 17.9.2-r2
Wolfi gitlab-exporter-scripts-17.8 0 17.8.4-r31
Wolfi gitlab-exporter-scripts-17.9 0 17.9.2-r2
Wolfi gitlab-geo-logcursor-scripts-17.8 0 17.8.4-r31
Wolfi gitlab-geo-logcursor-scripts-17.9 0 17.9.2-r2
Wolfi gitlab-gitaly-scripts-17.8 0 17.8.4-r31
Wolfi gitlab-gitaly-scripts-17.9 0 17.9.2-r2
Wolfi gitlab-logger-17.8 0 17.8.4-r31
Wolfi gitlab-logger-17.9 0 17.9.2-r2
Wolfi gitlab-logger-compat-17.8 0 17.8.4-r31
Wolfi gitlab-logger-compat-17.9 0 17.9.2-r2
Wolfi gitlab-mailroom-17.8 0 17.8.4-r31
Wolfi gitlab-mailroom-17.9 0 17.9.2-r2
Wolfi gitlab-mailroom-scripts-17.8 0 17.8.4-r31
Wolfi gitlab-mailroom-scripts-17.9 0 17.9.2-r2
Wolfi gitlab-pages-scripts-17.8 0 17.8.4-r31
Wolfi gitlab-pages-scripts-17.9 0 17.9.2-r2
Wolfi gitlab-rails-scripts-17.8 0 17.8.4-r31
Wolfi gitlab-rails-scripts-17.9 0 17.9.2-r2
Wolfi gitlab-shell-17.8 0 17.8.4-r31
Wolfi gitlab-shell-17.9 0 17.9.2-r2
Wolfi gitlab-shell-scripts-17.8 0 17.8.4-r31
Wolfi gitlab-shell-scripts-17.9 0 17.9.2-r2
Wolfi gitlab-shell-scripts-compat-17.8 0 17.8.4-r31
Wolfi gitlab-shell-scripts-compat-17.9 0 17.9.2-r2
Wolfi gitlab-sidekiq-scripts-17.8 0 17.8.4-r31
Wolfi gitlab-sidekiq-scripts-17.9 0 17.9.2-r2
Wolfi gitlab-toolbox-scripts-17.8 0 17.8.4-r31
Wolfi gitlab-toolbox-scripts-17.9 0 17.9.2-r2
Wolfi gitlab-webservice-config-17.8 0 17.8.4-r31
Wolfi gitlab-webservice-config-17.9 0 17.9.2-r2
Wolfi gitlab-webservice-scripts-17.8 0 17.8.4-r31
Wolfi gitlab-webservice-scripts-17.9 0 17.9.2-r2
Wolfi gitlab-workhorse-scripts-17.8 0 17.8.4-r31
Wolfi gitlab-workhorse-scripts-17.9 0 17.9.2-r2
Wolfi kube-fluentd-operator 0 1.18.2-r31
Wolfi kube-fluentd-operator-compat 0 1.18.2-r31
Wolfi kube-fluentd-operator-default-config 0 1.18.2-r31
Wolfi kube-fluentd-operator-oci-entrypoint 0 1.18.2-r31
Wolfi logstash-8 0 8.17.3-r2
Wolfi logstash-8-bitnami-compat 0 8.17.3-r2
Wolfi logstash-8-compat 0 8.17.3-r2
Wolfi logstash-8-env2yaml 0 8.17.3-r2
Wolfi logstash-8-iamguarded-compat 0 8.17.3-r2
Wolfi logstash-8-with-output-opensearch 0 8.17.3-r2
Wolfi ruby3.2-rails-8.0 0 8.0.2-r0
Wolfi ruby3.2-rails-8.0-compat 0 8.0.2-r0
Wolfi ruby3.3-rack-2.2 0 2.2.22-r0
Wolfi ruby3.4-rails-8.0 0 8.0.2-r0
Wolfi ruby3.4-rails-8.0-compat 0 8.0.2-r0
gem rack 3.0 3.0.14
gem rack 3.1 3.1.12
openSUSE:Leap 15.6 rubygem-rack 0 2.0.8-150000.3.26.1
openSUSE:Leap 15.6 rubygem-rack-1_6 0 1.6.8-150000.3.3.1
openSUSE:Tumbleweed rubygem-rack-2.2 0 2.2.13-1.1
openSUSE:Tumbleweed rubygem-rack-2.2 0 2.2.22-1.1

Related vulnerabilities