[Security] Fix CodeQL alert #30: Uncontrolled data used in path expression#98
[Security] Fix CodeQL alert #30: Uncontrolled data used in path expression#98colin-d-fried wants to merge 1 commit into
Conversation
| path = f"/documents/{doc}" | ||
| base_dir = os.path.realpath("/documents/") | ||
| path = os.path.realpath(os.path.join(base_dir, doc)) | ||
| if not path.startswith(base_dir): |
There was a problem hiding this comment.
🔴 Path traversal bypass via startswith check without trailing separator
os.path.realpath("/documents/") strips the trailing slash, yielding base_dir = "/documents". The check path.startswith(base_dir) on line 27 will therefore also match paths in sibling directories whose names share the same prefix (e.g., /documents_secret/). An attacker supplying doc=../documents_secret/passwd would produce path = "/documents_secret/passwd", which passes "/documents_secret/passwd".startswith("/documents") → True, bypassing the security check and reading arbitrary files.
The fix is to ensure the resolved path starts with base_dir + os.sep (or equals base_dir exactly).
| if not path.startswith(base_dir): | |
| if not (path == base_dir or path.startswith(base_dir + os.sep)): |
Was this helpful? React with 👍 or 👎 to provide feedback.
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
| path = f"/documents/{doc}" | ||
| base_dir = os.path.realpath("/documents/") | ||
| path = os.path.realpath(os.path.join(base_dir, doc)) | ||
| if not path.startswith(base_dir): |
There was a problem hiding this comment.
Path traversal fix bypassed via startswith without trailing separator
High Severity
The startswith check against base_dir is bypassable because os.path.realpath strips the trailing slash, leaving base_dir as "/documents". A sibling directory like "/documents_secret" would pass the path.startswith("/documents") check, allowing access to files outside the intended directory. The check needs to compare against base_dir + os.sep (or also allow path == base_dir) to be a correct path traversal guard.


Summary
Fixes CodeQL alert #30: Uncontrolled data used in path expression
vulnerable_path_traversal.pyFix Applied
See the diff for the specific secure coding change applied.
Fixes #32
Note
Medium Risk
Introduces path canonicalization and a base-directory check for user-supplied document paths, which can affect file access behavior and potentially block previously reachable paths. Low code churn, but touches security-sensitive file I/O and relies on correct path validation.
Overview
Fixes a path traversal risk in
view_documentby resolving the requesteddocpath against a canonical/documents/base directory and denying requests that escape that directory.Replaces string path construction with
os.path.realpath(os.path.join(...))and returns403on validation failure before reading the file.Written by Cursor Bugbot for commit 2b3a9cd. This will update automatically on new commits. Configure here.