CVE-2025-24961 Overview
CVE-2025-24961 is a path traversal vulnerability [CWE-22] in org.gaul S3Proxy, an application that implements the Amazon Simple Storage Service (S3) API and proxies requests to storage backends. Users of the filesystem and filesystem-nio2 storage backends could unintentionally expose local files on the host system to remote S3 API consumers. The flaw stems from insufficient validation of container names and blob keys, which allowed traversal sequences to escape the intended storage root. Maintainers addressed the issue in S3Proxy version 2.6.0.
Critical Impact
Authenticated S3 API clients can read local files outside the configured storage directory by supplying crafted container or object names containing parent-directory references.
Affected Products
- org.gaul S3Proxy versions prior to 2.6.0
- S3Proxy deployments using the filesystem storage backend
- S3Proxy deployments using the filesystem-nio2 storage backend
Discovery Timeline
- 2025-02-03 - CVE-2025-24961 published to the National Vulnerability Database (NVD)
- 2026-06-17 - Last updated in NVD database
Technical Details for CVE-2025-24961
Vulnerability Analysis
S3Proxy exposes an S3-compatible API and translates requests into operations against a backend storage system. When configured with the filesystem or filesystem-nio2 backend, container names map to directories and blob keys map to file paths beneath a configured root directory. The library did not reject inputs containing .. sequences or single-dot references, allowing the resolved path to leave the intended container directory. An authenticated caller could issue standard S3 operations such as GetObject with a manipulated key and retrieve arbitrary files readable by the S3Proxy process.
Root Cause
The underlying jclouds FilesystemBlobKeyValidatorImpl and FilesystemContainerNameValidatorImpl classes blocked leading path separators but did not reject embedded ../ sequences or dot-only container names. In the filesystem-nio2 backend, path resolution used Path.resolve without a subsequent normalize check to confirm the result remained under the container root. Both gaps enabled directory traversal via the standard S3 request surface.
Attack Vector
An attacker with valid credentials for the S3Proxy endpoint sends S3 API requests whose container name or object key contains parent-directory tokens. The proxy resolves the crafted path against the storage root, exits the intended directory, and returns file contents from elsewhere on the host filesystem.
// Patch: FilesystemBlobKeyValidatorImpl.java - reject traversal in blob keys
//blobkey cannot start with / (or \ in Windows) character
if (name.startsWith("\\") || name.startsWith("/"))
throw new IllegalArgumentException("Blob key '" + name + "' cannot start with \\ or /");
if (name.contains("../"))
throw new IllegalArgumentException("Blob key '" + name + "' cannot contains ../");
Source: apache/jclouds commit b0819e0
// Patch: FilesystemContainerNameValidatorImpl.java - reject dot-only container names
//container name cannot contains / (or \ in Windows) character
if (name.contains("\\") || name.contains("/"))
throw new IllegalArgumentException("Container name '" + name + "' cannot contain \\ or /");
if (name.equals(".") || name.equals(".."))
throw new IllegalArgumentException("Container name cannot be . or ..");
Source: apache/jclouds commit b0819e0
// Patch: AbstractNio2BlobStore.java - normalize and validate resolved path
var containerPath = root.resolve(container);
var pathPrefix = containerPath.resolve(prefix).normalize();
checkValidPath(containerPath, pathPrefix);
logger.debug("Listing blobs at: {}", pathPrefix);
Source: gaul/s3proxy commit 86b6ee4
Detection Methods for CVE-2025-24961
Indicators of Compromise
- S3 API requests whose bucket or object key contains ../, ..\, or dot-only segments in access logs.
- GetObject responses returning files that do not correspond to any legitimate uploaded blob.
- Access to S3Proxy paths that resolve outside the configured storage root directory.
Detection Strategies
- Inspect reverse-proxy or S3Proxy request logs for URL-decoded traversal sequences in the path or query string.
- Compare filesystem read events by the S3Proxy process against the configured backend root and alert on reads outside that tree.
- Correlate authenticated S3 API calls with unusual container names such as ., .., or names containing separators.
Monitoring Recommendations
- Enable verbose access logging on S3Proxy and forward logs to a centralized analytics platform for pattern searches.
- Baseline expected container and blob key naming conventions, then alert on deviations that include path metacharacters.
- Monitor the S3Proxy host for outbound reads of sensitive files such as /etc/passwd, credential stores, or configuration directories.
How to Mitigate CVE-2025-24961
Immediate Actions Required
- Upgrade S3Proxy to version 2.6.0 or later, which incorporates the jclouds validator and filesystem-nio2 normalization fixes.
- Rotate any credentials, tokens, or secrets that may have resided in files readable by the S3Proxy process account.
- Restrict network exposure of the S3Proxy endpoint to trusted clients until the upgrade is verified in production.
Patch Information
The fix landed in S3Proxy 2.6.0 through the changes in gaul/s3proxy commit 86b6ee4 and the upstream jclouds validators in apache/jclouds commit b0819e0. Additional context is available in GitHub Security Advisory GHSA-2ccp-vqmv-4r4x.
Workarounds
- No official workarounds exist; the vendor advisory states that upgrading is the only remediation.
- As defense in depth, run S3Proxy under a dedicated low-privilege user whose filesystem access is confined to the storage root via operating system permissions or a chroot/container boundary.
- Consider switching to a non-filesystem backend, such as an object storage service, when upgrading is not immediately feasible.
# Verify installed S3Proxy version and upgrade
s3proxy --version
# Example: upgrade the Docker image to a patched release
docker pull andrewgaul/s3proxy:2.6.0
docker stop s3proxy && docker rm s3proxy
docker run -d --name s3proxy \
--user 1000:1000 \
-v /srv/s3proxy/data:/data:rw \
-e S3PROXY_ENDPOINT=http://0.0.0.0:80 \
-e JCLOUDS_PROVIDER=filesystem \
-e JCLOUDS_FILESYSTEM_BASEDIR=/data \
andrewgaul/s3proxy:2.6.0
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.