AntFleet

Receipt · 3a9ae97b-0

Path traversal in ProjectManager via unvalidated project_id

securityhigh
repo 193af03f·PR #1·reviewed 1 week ago

The finding

  • backend/app/models/project.py:169-175
  • backend/app/models/project.py:245-260
  • backend/app/models/project.py:286-296
  • backend/app/api/graph.py:39-53
ProjectManager methods (_get_project_dir, _get_project_meta_path, _get_project_files_dir, _get_project_text_path, delete_project, save_extracted_text, save_file_to_project) all build filesystem paths by os.path.join(PROJECTS_DIR, project_id) without any validation that project_id is a safe identifier. The route `GET /api/graph/project/<project_id>` and the POST body of `/api/graph/build` accept arbitrary project_id strings and forward them straight to ProjectManager.get_project. A caller passing `project_id='../../something'` (allowed because Flask's default `<string>` converter accepts dots and slashes? — actually `<string>` disallows `/`, but JSON bodies in `/build` have no such constraint, and `..` alone is allowed even by the URL converter) causes the server to read/write/shutil.rmtree files outside the projects directory. Unlike report.py and share.py which use `validate_simulation_id`, no analogous validate_project_id exists. delete_project is especially dangerous because it shutil.rmtree's a path derived from user input.

Fix

Add a `validate_project_id` helper (mirroring `utils.validation.validate_simulation_id`) that enforces a strict regex like `^proj_[a-z0-9]{12}$`, and call it at the entry of every API route that takes project_id and inside ProjectManager.get_project / delete_project / save_file_to_project as defense in depth.

Agent attribution

The agents that produced this receipt — both reviewer models had to flag this independently for the agreement gate to emit it.

anthropic

gpt-5

119.3s · error

openai

claude-opus-4-7

121.8s · error

Total

wall-clock review time · est. inference cost

121.8s · $0.40

Sweeper

closed at SHA

still open

internal review id · 3a9ae97b

Third-party witnesses

Everything below lives on GitHub's event log, not ours. Click any link to verify the SHA, the timestamp, and the surrounding context for yourself.

AntFleet · Path traversal in ProjectManager via unvalidated project_id