Summary
Multiple API routes construct filesystem paths directly from user-supplied query parameters (casename, caserunname, file, dataJson) with zero validation or sanitization. An attacker can supply payloads like ../../etc/passwd or ....\Windows\System32\config\SAM to read or overwrite arbitrary files on the server. Additionally, UploadRoute.py calls zf.extractall() on user-uploaded ZIP files without checking entry paths, making it vulnerable to Zip Slip attacks.
Affected routes:
- CaseRoute.py — copyCase, deleteCase, updateData use casename directly in Path() construction
- DataFileRoute.py — downloadFile, downloadCSVFile, downloadResultsFile use file/caserunname in send_file()
- UploadRoute.py — zf.extractall() on user-uploaded ZIPs
Expected behavior
- A shared validation utility in Classes/Base/ should reject any path component containing .., /, , or null bytes
- After resolving the final path, the utility should verify it is within DATA_STORAGE
- All endpoints accepting user-supplied file/case names must call this validator before any filesystem operation
- ZIP extraction should validate each entry's destination path before writing
- Invalid inputs should return HTTP 400 with a clear JSON error message - never a 500
Reproduction steps
- Start the app: cd API && python app.py
- Send a request to the copy case endpoint with a traversal payload:
POST /case/copyCase
Content-Type: application/json
{"casename": "../../etc/passwd", "newcasename": "stolen"}
- Observe that the server attempts to copy from outside DataStorage/
- Send a download request with a traversal payload:
GET /dataFile/downloadFile?file=../../API/app.py&casename=test
- Observe that the server returns the contents of app.py (or any other file on the system)
- Upload a ZIP file containing an entry with path ../../../malicious.py and observe it gets extracted outside DataStorage/
Environment
- OS: Windows 11 / Ubuntu 22.04 / macOS (all affected)
- Python: 3.10+
- Branch: main
- Files: API/Routes/Case/CaseRoute.py, API/Routes/DataFile/DataFileRoute.py, API/Routes/Upload/UploadRoute.py
Logs or screenshots
# CaseRoute.py — no validation on casename
casename = request.json['casename']
path = Path(Config.DATA_STORAGE, casename) # attacker controls casename
# DataFileRoute.py — user-controlled path passed to send_file
file = request.args.get('file')
return send_file(Path(Config.DATA_STORAGE, casename, file))
# UploadRoute.py — no Zip Slip protection
zf.extractall(upload_dir) # entries could contain ../../../
Summary
Multiple API routes construct filesystem paths directly from user-supplied query parameters (casename, caserunname, file, dataJson) with zero validation or sanitization. An attacker can supply payloads like ../../etc/passwd or ....\Windows\System32\config\SAM to read or overwrite arbitrary files on the server. Additionally, UploadRoute.py calls zf.extractall() on user-uploaded ZIP files without checking entry paths, making it vulnerable to Zip Slip attacks.
Affected routes:
Expected behavior
Reproduction steps
GET /dataFile/downloadFile?file=../../API/app.py&casename=testEnvironment
Logs or screenshots