Aug 25, 2026·7 min read·1 visit
Authenticated users can write files outside target directories by exploiting missing path-traversal validation in Cloudreve's integration with remote downloaders like aria2.
A path traversal vulnerability exists in Cloudreve's remote download workflow, where improper sanitization of file paths returned by configured remote downloaders (such as aria2) allows authenticated users to write files outside the designated target folder.
Cloudreve is an open-source, multi-protocol file management system implemented in Go, which allows users to aggregate multiple storage strategies under a unified interface. A critical component of Cloudreve is its remote download workflow, which integrates with external downloaders like aria2. This integration relies on communication via JSON-RPC to monitor download states and retrieve metadata about completed transfers.
The remote download workflow exposes an attack surface where Cloudreve processes file paths returned directly by the external downloader daemon. The application relies on a validation function, sanitizeFileName, to ensure that filenames received from external systems do not contain dangerous sequences. However, because this function only filters system-specific characters such as colons and backslashes, it fails to neutralize directory traversal structures.
This validation deficiency leads to CWE-22 (Improper Limitation of a Pathname to a Restricted Directory) and CWE-23 (Relative Path Traversal). The impact is limited to users with permissions to configure or execute remote downloads, but it allows for arbitrary file write placement within the virtual URI namespace. This can bypass directory-level boundaries, access control lists, and user-configured storage quota restrictions.
The vulnerability originates in pkg/filemanager/workflows/remote_download.go within the sanitizeFileName function. This function uses Go's strings.NewReplacer to replace invalid characters like backslashes, colons, asterisks, and quotes with underscores. However, it completely omits forward slashes (/) and dots (.), which are the primary building blocks of path traversal strings in Unix-like environments.
When a remote download task completes, Cloudreve queries the downloader daemon using RPC methods to fetch the status of the files. The file metadata returned contains the local path where the downloader saved the file. Cloudreve extracts the filename by trimming the configured download save path from this string. The resulting relative path is then passed directly to sanitizeFileName and subsequently processed.
Because sanitizeFileName leaves traversal sequences untouched, a path containing ../../escaped.txt remains unchanged. The application then passes this string to the URI-joining component of its internal file system implementation. This processing chain allows the untrusted relative path to influence the final physical or virtual storage location.
The resolution of these relative segments occurs inside JoinRaw, which splits the input string by path separators and sequentially applies the directory movements to the base URI. When encountering the .. elements, the URI resolver moves up the directory tree past the intended sandbox base directory. This is the logical core of the vulnerability, where trusted virtual namespace paths are programmatically overridden by the untrusted downloader input.
To understand the vulnerable code path, we must inspect the sanitizeFileName implementation and its application during target path resolution. The following code block shows the vulnerable sanitizer and the two vulnerable assembly points in pkg/filemanager/workflows/remote_download.go:
// Vulnerable sanitizer in pkg/filemanager/workflows/remote_download.go
func sanitizeFileName(name string) string {
// This replacer lacks rules for forward slashes (/) and dots (.)
r := strings.NewReplacer("\\", "_", ":", "_", "*", "_", "?", "_", "\"", "_", "<", "_", ">", "_", "|", "_")
return r.Replace(name)
}During the download completion process, the master node retrieves the file.Name value from the downloader driver's response payload. It processes this value using the vulnerable sanitizer and then appends it to the destination URI using the vulnerable JoinRaw method:
// Insecure assembly on Master Node (remote_download.go)
sanitizedName := sanitizeFileName(file.Name) // Returns "../../escaped.txt"
dst := dstUri.JoinRaw(sanitizedName) // Resolves outside the base directory
src := filepath.FromSlash(path.Join(m.state.Status.SavePath, file.Name))Similarly, slave nodes that process remote downloads construct the transfer entities using the same insecure pattern. They register the uploaded entities with the resolved destination paths, allowing files to bypass target storage directories during clustered node synchronization:
// Insecure assembly on Slave Node (remote_download.go)
dst := dstUri.JoinRaw(sanitizeFileName(f.Name)) // Insecure resolution
src := path.Join(m.state.Status.SavePath, f.Name)
payload.Files = append(payload.Files, SlaveUploadEntity{
Src: src,
Uri: dst,
})The JoinRaw function in pkg/filemanager/fs/uri.go splits the argument and routes the individual directory steps directly to the URI's Join method. Because Join resolves parent directories incrementally when it encounters .., the structure is walked back beyond the root of the targeted folder, resulting in out-of-bounds file placement.
Exploitation of this vulnerability requires that an attacker have the privileges necessary to schedule remote download tasks in Cloudreve. This configuration is typically restricted to authenticated users or administrators, depending on the system's access control policy. An attacker can execute the exploit using one of two primary attack vectors.
The first vector involves configuring Cloudreve's remote download agent to point to a malicious JSON-RPC server hosted on an attacker-controlled endpoint. When Cloudreve queries this server for download status updates, the server returns manipulated file paths containing relative traversal sequences. The backend blindly trusts the response and places the files in the traversed path.
The second vector is more direct and does not require modifying the RPC endpoint. An attacker can upload a multi-file torrent or metafile download task where the torrent internal file structure contains relative paths (e.g., ../../escaped.txt). If the legitimate aria2 daemon downloads this torrent, it reports the internal relative file paths back to Cloudreve, which processes them using the vulnerable sanitizeFileName routine.
The expected outcome of successful exploitation is the placement of download payloads into arbitrary directories within the Cloudreve storage provider workspace. While this does not automatically grant operating system-level arbitrary code execution, it allows an attacker to bypass file access boundaries, write malicious scripts into web-accessible folders, or overwrite other users' files within the virtual URI namespace.
This vulnerability has been assigned a CVSS v4.0 score of 5.5 (Medium Severity). The vulnerability's attack vector is Network, and it requires low complexity and no user interaction from other victims. However, it does require authenticated privileges to initiate download tasks, which dampens the severity rating compared to unauthenticated remote code execution bugs.
The primary impact of the flaw is a loss of integrity. An attacker can write files to arbitrary locations in the Cloudreve virtual file system. In multi-user setups, this allows a tenant to write files to folders owned by other users or administrators, exposing private storage spaces to unauthorized additions.
Depending on the configured storage backend, the traversal can have additional side effects. If Cloudreve is configured with local file storage and virtual paths reflect direct disk directories, path traversal could allow writing files to arbitrary paths on the host filesystem. This scenario elevates the severity to potential remote code execution if the attacker can overwrite executable binaries or configuration files.
At the time of this analysis, there are no records of active exploitation in the wild, and the vulnerability is not listed in CISA's Known Exploited Vulnerabilities catalog. The exploit maturity is classified as Proof of Concept, as the technical mechanics are well-documented but require specific environmental conditions to achieve significant malicious impact.
To mitigate this vulnerability, users must restrict remote download scheduling permissions to highly trusted accounts. If possible, disable external downloader integrations (such as aria2) until a robust validation patch is applied to the Cloudreve codebase. Additionally, restrict network access to the aria2 JSON-RPC endpoint to prevent unauthorized configuration modifications.
A complete programmatic fix requires modifying sanitizeFileName in pkg/filemanager/workflows/remote_download.go. The function should be updated to strip path traversal sequences using standard Go library methods like filepath.Clean and strings.ReplaceAll to remove relative directory shifts:
func sanitizeFileName(name string) string {
r := strings.NewReplacer("\\", "_", ":", "_", "*", "_", "?", "_", "\"", "_", "<", "_", ">", "_", "|", "_")
name = r.Replace(name)
name = filepath.Clean(name)
name = strings.TrimPrefix(name, "..")
name = strings.ReplaceAll(name, "..", "")
name = strings.TrimPrefix(name, "/")
return name
}Furthermore, the URI-joining workflow must perform boundary checks. When joining a base URI with user-supplied relative path fragments, the application must verify that the resulting URI retains the original base URI as its prefix. If the resolved path escapes the parent directory, the application must abort the operation and return an access violation error.
func SafeJoinRaw(baseUri *URI, elem string) (*URI, error) {
sanitized := sanitizeFileName(elem)
dst := baseUri.JoinRaw(sanitized)
if !strings.HasPrefix(dst.String(), baseUri.String()) {
return nil, errors.New("path traversal attempt detected")
}
return dst, nil
}CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:L/VA:N/SC:N/SI:N/SA:N/E:P| Product | Affected Versions | Fixed Version |
|---|---|---|
Cloudreve Cloudreve | <= 4.0.0-20260606032813-26b6b1044b02 | None |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-22 |
| Attack Vector | Network |
| CVSS v4.0 | 5.5 |
| Exploit Status | PoC Available |
| Impact | Partial Integrity (Unintended File Placement) |
| Privileges Required | Authenticated User |
The software uses external input to construct a pathname that should be within a restricted directory, but it does not properly neutralize sequences such as '..' that can resolve to a location outside of the restricted directory.
MHSanaei 3X-UI is a web control panel for managing Xray-core servers. In versions prior to 3.3.1, an authenticated administrator can abuse database import functions or raw template config fields to overwrite or append to arbitrary files on the host filesystem. This is achieved by altering the Xray log configuration variables to target system files, leveraging logging components to inject payloads.
Cloudreve is vulnerable to an incorrect authorization bypass. When listing files, Cloudreve returns a context_hint (represented as a UUID) to the client. If this context hint is replayed on the /file/url or /file/thumb routes, Cloudreve's database file system caches the shareNavigatorState containing the loaded share root. Within the cache lifetime (TTL of 300 seconds), if the user re-requests the same file with the cached hint, the system restores the state and completely bypasses the root security checks (which validate share expiration, remaining download limits, owner status, and passwords). This allows unauthorized users to continue generating signed file URLs and downloading files even after a share has been deleted, has expired, or has reached its download limit.
An integer overflow vulnerability exists in the HTTP/1.x chunked encoding parser of the vibeio-http library. The flaw is caused by unchecked integer addition when calculating the total buffer size required for processing parsed chunk lengths. By sending a maliciously crafted HTTP request containing an extremely large chunk size, an unauthenticated remote attacker can trigger a runtime panic, leading to complete denial of service.
netfoil, an allowlist-based DNS proxy, failed to sanitize ALPN fields parsed from untrusted DNS-over-HTTPS (DoH) HTTPS Resource Records. This allowed attackers to inject ANSI escape sequences into log files or trigger Denial of Service (DoS) via uncontrolled memory allocations.
An issue was discovered in the tokio-postgres library for Rust prior to version 0.7.18. A trust assumption mismatch between the PostgreSQL protocol messages sent by a server and how they are parsed and indexed by the client-side library allows a rogue or compromised database server to trigger a Denial of Service (DoS) crash via an unhandled out-of-bounds slice indexing panic.
CVE-2026-14669 is a critical heap-based buffer overflow vulnerability in PostgreSQL's date/time formatting function to_char(timestamptz). The flaw arises from unsafe copying of user-controlled timezone abbreviations into a fixed-size internal buffer. An authenticated database user can trigger this issue by setting a long POSIX timezone abbreviation containing custom formatting, allowing them to overwrite adjacent heap structures and hijack execution control to achieve remote code execution (RCE) with the privileges of the 'postgres' operating system user.