CVEReports
CVEReports

Automated vulnerability intelligence platform. Comprehensive reports for high-severity CVEs generated by AI.

Product

  • Home
  • Sitemap
  • RSS Feed

Company

  • About
  • Contact
  • Privacy Policy
  • Terms of Service

© 2026 CVEReports. All rights reserved.

Made with love by Amit Schendel & Alon Barad



GHSA-PMWX-RM49-XV39

GHSA-PMWX-RM49-XV39: Path Traversal in ActiveRecord::Tenanted::Storage::DiskService

Alon Barad
Alon Barad
Software Engineer

Jul 29, 2026·6 min read·22 visits

Executive Summary (TL;DR)

A path traversal vulnerability in `activerecord-tenanted` allows attackers to read or write arbitrary files on the host system by manipulating ActiveStorage keys.

A directory traversal vulnerability exists in the `activerecord-tenanted` Ruby gem's local storage path resolution logic. Prior to version 0.7.0, the `path_for` method failed to sanitize input keys, allowing remote attackers to traverse directories and access arbitrary files on the host filesystem.

Vulnerability Overview

The activerecord-tenanted library is a Ruby gem designed to facilitate multi-tenancy configurations within applications using Ruby on Rails and ActiveRecord. Specifically, it provides mechanisms to segment data and physical storage resources based on the active tenant context. A critical component of this segmentation is the local disk storage coordination layer, which overrides default ActiveStorage behaviors to route asset storage into tenant-specific directory subfolders.

A security vulnerability, designated as GHSA-PMWX-RM49-XV39, exists in versions prior to 0.7.0. The vulnerability is classified as a Path Traversal (CWE-22) flaw. It resides in the custom implementation of the path_for method within ActiveRecord::Tenanted::Storage::DiskService.

Under vulnerable configurations, the path resolution routine does not sanitize, canonicalize, or validate key parameters containing directory traversal sequences. This allows unauthenticated remote attackers to step outside the bounds of the designated active storage root folder. The flaw enables unauthorized read or write operations on arbitrary files on the host system, subject to the permissions of the application process.

Root Cause Analysis

To understand the technical root cause, we must examine how the activerecord-tenanted gem overrides the path generation logic of Rails ActiveStorage. When local disk storage is used, the system invokes ActiveRecord::Tenanted::Storage::DiskService#path_for(key) to determine the absolute file path on disk.

The vulnerable implementation uses standard string manipulation and directory joining via File.join without verification of the resulting path. It checks if the requested blob key contains a forward slash to separate the tenant prefix from the file identifier. It then constructs the final filesystem path using the schema File.join(root, tenant, folder_for(key), key).

This design makes the fundamental assumption that both the tenant segment and the key segment are safe, well-formed directory components. However, File.join merely concatenates path components using system directory separators. It does not perform path canonicalization, nor does it collapse relative directory references such as double-dots.

Because the system fails to verify that the resolved physical path resides within the intended parent directory, any input containing traversal sequences escapes the storage boundaries. Attackers can provide keys containing sequence paths that logically point to sensitive system resources.

Code Analysis

The vulnerable implementation of the path resolution method exhibits a clear lack of input validation. The code block below represents the state of the component prior to the release of version 0.7.0.

def path_for(key)
  if ActiveRecord::Tenanted.connection_class && key.include?("/")
    tenant, key = key.split("/", 2)
    File.join(root, tenant, folder_for(key), key)
  else
    super
  end
end

By contrast, the patch introduced in version 0.7.0 adds substantial defensive validation layers to prevent directory traversal. The corrected method utilizes strict prefix matching and segment analysis to validate path inputs before returning a resolved path.

def path_for(key)
  return super unless ActiveRecord::Tenanted.connection_class && key.include?("/")
 
  # Block keys containing relative directory traversal elements
  if key.split("/").intersect?(%w[. ..])
    raise ActiveStorage::InvalidKeyError, "key has path traversal segments"
  end
 
  tenant, key = key.split("/", 2)
 
  # Check for blank path components
  if tenant.blank? || key.blank?
    raise ActiveStorage::InvalidKeyError, "key has a blank segment"
  end
 
  begin
    # Resolve the physical, canonical absolute path
    path = File.expand_path(File.join(root, tenant, folder_for(key), key))
  rescue ArgumentError
    raise ActiveStorage::InvalidKeyError, "key is an invalid string"
  end
 
  # Validate that the resolved path begins with the storage root
  unless path.start_with?(File.expand_path(root) + "/")
    raise ActiveStorage::InvalidKeyError, "key is outside of disk service root"
  end
 
  path
rescue Encoding::CompatibilityError
  raise ActiveStorage::InvalidKeyError, "key has incompatible encoding"
end

The primary defense in the updated method is the validation that the absolute path, computed via File.expand_path, begins with the expanded disk service root path. The check path.start_with?(File.expand_path(root) + "/") ensures that the path cannot traverse outside of the designated storage root.

Exploitation Methodology

Exploitation of this vulnerability requires that an attacker have a mechanism to submit or influence the storage keys processed by the ActiveStorage subsystem. This is often possible in applications that accept user-provided file uploads, utilize direct uploads, or resolve assets based on client-controlled identifiers.

An attacker can exploit the vulnerability by supplying a crafted key parameter that incorporates directory traversal sequences. For instance, the sequence ../../../../etc/passwd would split into a tenant segment of .. and a key segment of ../../../etc/passwd.

When the application invokes DiskService#path_for with the crafted key, the system resolves the logical path to /etc/passwd. Depending on the operation performed (read or write), the application will either disclose sensitive system configurations or overwrite files on the host container.

Impact Assessment

The impact of this vulnerability depends heavily on the role of ActiveStorage in the target application. If the application exposes endpoints that retrieve files by their keys, the directory traversal allows arbitrary file reading, resulting in the disclosure of application source code, environment variables, database credentials, and system files.

If the application enables file uploads where the key can be controlled or influenced by the client, the attacker can write or overwrite arbitrary files. This capability could lead to remote code execution if the attacker overwrites application executables, configuration files, or uploads a web shell to a directory parsed by the web server.

The vulnerability has an estimated CVSS score of 9.1 (Critical) due to the low complexity of exploitation and the potential for complete loss of confidentiality and integrity. The risk is heightened because file-upload and retrieval logic often operates under unauthenticated sessions.

Remediation and Mitigation Guidance

The definitive resolution for GHSA-PMWX-RM49-XV39 is upgrading the activerecord-tenanted gem to version 0.7.0 or higher. This upgrade implements the necessary input validation checks and absolute path verification rules.

Because version 0.7.0 of the gem relies on ActiveStorage::InvalidKeyError, you must also upgrade your Ruby on Rails framework dependencies to version 8.1.2.1 or higher. This ensures that the custom disk service can raise the appropriate exception when encountering malicious keys.

# Update Gemfile
gem 'activerecord-tenanted', '>= 0.7.0'

If upgrading is not immediately feasible, you can implement a temporary hotfix by creating an initializer that intercepts calls to DiskService#path_for and raises an error if the key contains dot-dot sequences or null bytes. Additionally, ensure the application process runs with the minimum necessary filesystem privileges.

Fix Analysis (1)

Technical Appendix

CVSS Score
9.1/ 10
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N

Affected Systems

Ruby on Rails applications using activerecord-tenanted and local disk storage

Affected Versions Detail

Product
Affected Versions
Fixed Version
activerecord-tenanted
Basecamp
< 0.7.00.7.0
AttributeDetail
CWE IDCWE-22
Attack VectorNetwork (AV:N)
CVSS Score9.1
Exploit Statuspoc
KEV StatusNot Listed

MITRE ATT&CK Mapping

T1083File and Directory Discovery
Discovery
T1567Exfiltration Over Web Service
Exfiltration
CWE-22
Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal')

The software uses external input to construct a pathname that is intended to identify a file or directory that is located under a restricted parent directory, but the software does not properly neutralize special elements within the pathname that can cause the pathname to resolve to a location that is outside of the restricted directory.

Vulnerability Timeline

Vulnerability fix committed and PR #307 merged
2026-06-08
GitHub Security Advisory GHSA-PMWX-RM49-XV39 published
2026-06-08
activerecord-tenanted version 0.7.0 released
2026-06-08

References & Sources

  • [1]GitHub Security Advisory Page
  • [2]Repository Security Advisory
  • [3]Fix Pull Request #307
  • [4]Vulnerability Fix Commit
  • [5]v0.7.0 Release Page

Attack Flow Diagram

Press enter or space to select a node. You can then use the arrow keys to move the node around. Press delete to remove it and escape to cancel.
Press enter or space to select an edge. You can then press delete to remove it or escape to cancel.

More Reports

•25 minutes ago•CVE-2026-107848
3.5

CVE-2026-107848: Cross-Site Request Forgery (CSRF) in Contao Backend Actions via GET Requests

Contao Open Source CMS versions 4.0.0 through 5.3.49 and 5.4.0-RC1 through 5.7.11 contain a Cross-Site Request Forgery (CSRF) vulnerability in backend parameter handling. The `RequestTokenListener` component validates anti-CSRF tokens solely for HTTP POST requests, while GET-based declarative guards run only when an `act` parameter is present in the query string. Consequently, custom backend actions dispatched via alternative parameters such as `key=` can execute without CSRF token verification when triggered by an authenticated user.

Amit Schendel
Amit Schendel
1 views•5 min read
•about 2 hours ago•CVE-2026-107843
5.3

CVE-2026-107843: Unthrottled Activation Email Resend and Account Enumeration in Contao CMS

Contao CMS versions 4.1.0 through 5.3.49 and 5.4.0-RC1 through 5.7.11 fail to validate form submission tokens and enforce rate limiting when processing activation email resend requests via HTTP POST, enabling resource exhaustion and account state enumeration.

Amit Schendel
Amit Schendel
4 views•4 min read
•about 2 hours ago•CVE-2026-107842
5.3

CVE-2026-107842: Information Disclosure via Stale Indexing in Contao Search Module

An information disclosure vulnerability in Contao CMS allows unauthenticated site visitors to view protected page titles, URLs, and text excerpts through search queries when protected page indexing is disabled after previously being enabled.

Amit Schendel
Amit Schendel
7 views•4 min read
•about 4 hours ago•GHSA-G38J-7V97-X298
6.5

GHSA-G38J-7V97-X298: Missing Authorization Check in Vikunja CalDAV Task Relation Creation

In Vikunja prior to version 2.6.0, relation creation via the CalDAV endpoint fails to invoke the TaskRelation.CanCreate authorization check. This missing access control allows an authenticated user to establish unauthorized relationships and perform write operations against any task, provided its unique identifier (UID) is known.

Alon Barad
Alon Barad
8 views•5 min read
•about 5 hours ago•GHSA-3HC7-R24J-RPWC
6.8

GHSA-3hc7-r24j-rpwc: Cross-Project Task Disclosure via Subtask Expansion in Vikunja

A cross-project information disclosure vulnerability in Vikunja allows authenticated users with read access to one project to view private task details from unauthorized projects via subtask expansion parameters.

Alon Barad
Alon Barad
8 views•5 min read
•about 5 hours ago•GHSA-8WVG-R2J4-3737
4.3

GHSA-8wvg-r2j4-3737: Email Address Exposure in Vikunja Task Assignees API

An information disclosure vulnerability in Vikunja allows authenticated users with read access to a task to expose private email addresses of assigned users through the API task assignees endpoint due to an unmasked database query.

Amit Schendel
Amit Schendel
8 views•5 min read