BUG_Author: Zy0t1
Affected Version: flow-ci / flow-core-x all versions (since 2019 to master branch, never patched)
Vendor: FlowCI/flow-core-x
Software: flow-ci
Vulnerability Files: - store/src/main/java/com/flowci/store/LocalFileManager.java (L56, L67, L75, L87, L94 — 5 sinks in exist, save, read, remove methods)
CWE: 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 located beneath a restricted parent directory, but it does not properly neutralize special elements such as ../ sequences that can resolve to a location that is outside of that directory.
CVSS 3.1: 7.5 (High) - AV:N/AC:H/PR:L/UI:N/S:U/C:H/I:H/A:H
flow-ci's LocalFileManager implementation constructs file paths with Paths.get(dir.toString(), fileName) and passes them directly to filesystem operations. The fileName parameter is not sanitized: there is no detection of .., no normalize() call, and no startsWith(base) boundary check. Java's Paths.get(a, b) preserves .. path components, so a filename such as ../../../../cve02_browser_escape.txt can escape the intended storage directory when the operating system resolves the path.
Five vulnerable sinks exist:
exist() — L56: Paths.get(dir.toString(), fileName) — traversal-aware existence check.save() — L67: Paths.get(dir.toString(), fileName) — arbitrary file write.read() — L75: Paths.get(dir.toString(), fileName) — arbitrary file read.remove(fileName, ...) — L87: Paths.get(dir.toString(), fileName) — arbitrary file delete.remove(filePath) — L94: Paths.get(filePath) — deletes a fully attacker-controlled path.Several HTTP entry points pass user-controlled names to the storage layer:
POST /secrets/android/sign — keyStore.getOriginalFilename() from a multipart upload.POST /api/flow/{name}/job/{number}/artifact — file.getOriginalFilename().POST /api/cache/{jobId}/{key}/{os} — file.getOriginalFilename().GET /api/cache/{cacheId}?file=<...> — direct @RequestParam String file.