fix: prevent path traversal in ClaudeAPIClient._read_file()#79
Open
qinlongli2024-ai wants to merge 1 commit intoanthropics:mainfrom
Open
fix: prevent path traversal in ClaudeAPIClient._read_file()#79qinlongli2024-ai wants to merge 1 commit intoanthropics:mainfrom
qinlongli2024-ai wants to merge 1 commit intoanthropics:mainfrom
Conversation
The _read_file() method in ClaudeAPIClient accepted file paths from untrusted security findings without validating that the resolved path stayed within the repository root. An attacker could craft a finding with a file field like '../../../etc/shadow' to read arbitrary files from the CI runner, with their contents sent to the Claude API prompt. Changes: - Reject absolute paths outright (never legitimate from findings) - Resolve the candidate path with os.path.realpath() to collapse '..' segments and follow symlinks to their true destination - Verify the resolved path starts with the repository root + os.sep to prevent partial-prefix false positives - Reject empty and whitespace-only paths early - Add comprehensive test suite (14 tests) covering: - happy-path reads (relative, root-level, latin-1 fallback) - traversal via '..' sequences - absolute path injection - symlink escape attacks - edge cases (empty, whitespace, directory, nonexistent) - fallback behavior when REPO_PATH is unset This approach mirrors the validated path-checking pattern used in the sibling claude-code-action project (src/mcp/path-validation.ts).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
_read_file()inClaudeAPIClientaccepts file paths from untrusted security findings without validating that the resolved path stays within the repository root. A malicious PR could craft a finding with"file": "../../../etc/shadow"to exfiltrate arbitrary files from the CI runner — their contents are included verbatim in the prompt sent to the Claude API.Attack scenario
claude-code-security-review.../../../etc/shadow,../../../home/runner/.ssh/id_rsa)._read_file()follows the..segments, reads the sensitive file, and embeds its content in the Claude API prompt.Symlink-based escapes are also possible: a repo could include a symlink like
data/config -> /etc/passwd, and the old code would follow it without complaint.Fix
os.path.realpath()— collapses..segments and follows symlinks to their true destination.repo_root + os.septo prevent partial-prefix bypasses (e.g.,/repo-datamatching/repo).This mirrors the validated path-checking pattern already used in the sibling claude-code-action project (
src/mcp/path-validation.ts).Tests
Added 14 test cases covering:
../traversal (direct and prefixed)/etc/passwd)REPO_PATHunset fallback)All 14 tests pass.
Checklist