mirror of
https://github.com/soxoj/maigret.git
synced 2026-05-13 18:05:39 +00:00
f413603431
The previous /reports/<path:filename> handler resolved the filename with os.path.normpath and gated send_file on file_path.startswith(REPORTS_FOLDER). Plain ../ traversal was rejected because the resolved path no longer started with REPORTS_FOLDER, but a sibling-prefix variant slipped through: a request of the form ..%2F<reports_root_basename>2/<file> resolves to a path like /tmp/maigret_reports2/<file>, which still starts with /tmp/maigret_reports and was served back to the caller. Replace the manual normpath+startswith check with Flask's send_from_directory, which delegates to werkzeug.security.safe_join. safe_join enforces a real boundary against the resolved directory, rejects absolute paths, and refuses .. segments that escape the root. Tests: 4 new test_download_report_* cases in tests/test_web.py covering the happy path, ../ traversal, the sibling-prefix bypass (regression test — fails on the pre-fix code, passes on the new code), and absolute paths. Detected by Aeon + manual review of maigret.web.app. Severity: low (web UI defaults to FLASK_HOST=127.0.0.1; the Docker `web` target binds 0.0.0.0; exploitation reads files from sibling /tmp directories, which is bounded by who can place files there). CWE-22. Co-authored-by: aeonframework <aeon-bot@aaronjmars.com>