fix: harden path validation against traversal and Windows drive escape - #809
Conversation
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
|
Caution Review failedPull request was closed or merged during review No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (6)
📝 WalkthroughWalkthroughPath validation logic is hardened across multiple modules by replacing string-based comparisons with resolved Path containment checks. The API utils now enforce allow-lists using Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches
🧪 Generate unit tests (beta)
📝 Coding Plan
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Issue #672: Replace os.path.commonpath string comparison in resolve_path() with Path.resolve().is_relative_to() — correctly handles symlinks, ".." sequences, and path-prefix spoofing (e.g. /allowed_dir_extra passing a startswith check against /allowed_dir). Also replace str.startswith() in FileMover._is_already_in_category() with the same pattern. Issue #760: Extend StageContext._validate_path_component() to reject Windows drive-qualified values such as "C:" and "C:docs" that carry no slash but still produce a non-empty PureWindowsPath.drive/.anchor, allowing output_dir / category to escape the intended output directory on Windows. Adds regression tests for both construction-time and setattr assignment paths. Update tests/ci/test_path_security_contract.py allowlists to match the new resolve_path() implementation (Path.expanduser().resolve() instead of os.path.realpath). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
05fd5e0 to
aa2b3a2
Compare
Summary
str.startswith()/os.path.commonpathpath checks withPath.resolve().is_relative_to()inresolve_path()(api/utils.py) andFileMover._is_already_in_category()(methodologies/para/ai/file_mover.py) — prevents symlink escape and..traversal attacksoutput_dir / categoryto escape the intended output directory. Consider rejecting Windows drive/anchor patterns (e.g., viaPureWindowsPath(value).drive/.anchor) and add a regression test forcategory='C:'/filename='C:'. #760: Reject Windows drive-qualified path components (C:,C:docs) inStageContextfield validation — preventsoutput_dir / categoryescape on Windows viaPureWindowsPath.drive/.anchorbeing non-empty even without any slashtest_path_security_contract.pyallowlists to match the newresolve_path()implementationTest plan
test_path_prefix_attack_blocked,test_dotdot_traversal_via_subdirectory_blocked,test_symlink_escaping_allowed_root_blocked)test_rejects_windows_drive_in_category,test_rejects_windows_drive_with_path_in_category,test_rejects_windows_drive_in_filename,test_rejects_windows_drive_in_filename_via_setattr)Closes #672, closes #760
🤖 Generated with Claude Code
Summary by CodeRabbit
Bug Fixes
Tests