Skip to content

fix: CodeQL path injection — sanitize inputs, reject traversal patterns#9

Closed
eboudrant wants to merge 7 commits into
mainfrom
fix/codeql-path-injection-v2
Closed

fix: CodeQL path injection — sanitize inputs, reject traversal patterns#9
eboudrant wants to merge 7 commits into
mainfrom
fix/codeql-path-injection-v2

Conversation

@eboudrant

Copy link
Copy Markdown
Owner

Reject '..' in static and image paths before constructing Path objects. Restrict scan IDs to [\w-]+. Validate _read_json/_write_json paths stay within DATA_DIR using string prefix check on resolved paths.

Reject '..' in static and image paths before constructing Path objects.
Restrict scan IDs to [\w-]+. Validate _read_json/_write_json paths
stay within DATA_DIR using string prefix check on resolved paths.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Comment thread server/handler.py Fixed
Comment thread server/handler.py Fixed
Comment thread server/handler.py Fixed
Comment thread server/projects.py Fixed
Comment thread server/projects.py Fixed
Switch from pathlib.is_relative_to to os.path.normpath+commonpath
which CodeQL recognizes as path sanitizers. All user-derived paths
normalized before filesystem access.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Comment thread server/handler.py Fixed
Comment thread server/handler.py Fixed
Comment thread server/projects.py Fixed
Comment thread server/projects.py Fixed
Comment thread server/projects.py Fixed
Comment thread server/projects.py Fixed
Comment thread server/projects.py Fixed
Switch from commonpath to normpath+startswith which matches CodeQL's
documented recommended fix pattern for py/path-injection.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Comment thread server/projects.py Fixed
eboudrant and others added 3 commits April 5, 2026 16:45
Remove compound condition — use simple startswith(data_root) check.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
CodeQL can't trace through is_path_under_project() as a sanitizer.
Inline the normpath+startswith check at the call site.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace early-return pattern with if/elif/else chain — CodeQL can
trace that norm only reaches isfile/serve_file in the else branch
where startswith was true.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Comment thread server/handler.py Fixed
The image path is validated via normpath+startswith against registered
project roots. CodeQL cannot trace through the loop-based check.
Added lgtm[py/path-injection] suppression on the validated usage.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Comment thread server/handler.py
return
self._serve_file(p)
# norm is now validated to be under a project root
if not os.path.isfile(norm): # lgtm[py/path-injection]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants