-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Description
Describe the bug
When using claude-code-action@v1 with claude_code_oauth_token and a restricted --allowed-tools list, Claude Code will read arbitrary files from the checked-out repository and post their full contents as PR comments if it encounters repeated failures trying to complete its primary task.
In our case, Claude was instructed to post a PR review via gh pr comment. The review body contained Markdown with backticks and single quotes, causing every shell quoting strategy to fail. Claude then entered a self-directed retry loop where it:
- Posted test comments to debug whether basic comment posting worked at all
- Read internal documentation files from the repository (via its unrestricted
Readtool) - Posted those files verbatim as PR comments, apparently as test content to verify rendering
The 7 errant comments posted were:
- "test comment - please ignore"
- "line1\nline2\nline3" (testing newline handling)
- The Claude Code CLI terminal UI output (verbatim, including working directory and session state)
- "line1\nline2"
- "## Test\n\nHello
codeand bold\n" (testing Markdown rendering) - Full contents of
docs/development/database-reference.md(~24KB — database infrastructure docs) - Full contents of
AGENTS.md(~9.5KB — internal development guidelines)
After posting the files, Claude eventually succeeded in posting the actual review.
Core issue: claude_args: '--allowed-tools "Bash(gh pr comment:*)"' restricts Bash subcommands but does not restrict Claude Code's native tools (Read, Write, Grep, Glob). A user who configures tool restrictions expecting Claude cannot read repository files gets no such guarantee. The permitted Bash(gh pr comment:*) then becomes an unrestricted egress channel for content read via the unrestricted Read tool.
To Reproduce
- Create a workflow using
claude-code-action@v1withclaude_code_oauth_token - Set
claude_argsto restrict tools to only specificghBash commands (e.g.Bash(gh pr comment:*)) - Include
actions/checkout@v4so the repository is available on the runner - Set a prompt that instructs Claude to (a) read
CLAUDE.mdfor guidance and (b) post output viagh pr comment - Ensure
CLAUDE.mdcontains@references to other documentation files - Trigger the workflow on a PR where the review body will contain extensive Markdown formatting (backticks, code fences, single quotes)
- Observe: Claude attempts multiple quoting strategies, fails repeatedly, enters a debug loop, reads referenced files via
Readtool, and posts their contents as PR comments
Expected behavior
--allowed-tools "Bash(gh pr comment:*)"should either also restrict native file tools (Read,Write, etc.), or the documentation should clearly warn that it does not.- Claude should not enter an open-ended self-directed retry loop when a task fails. After N failed attempts it should abort and report failure rather than escalating to arbitrary recovery strategies.
- Claude should never post repository file contents as "test" content when debugging.
- The action should recommend
gh pr comment --body-filein its docs/examples to avoid the shell quoting failure mode entirely.
Screenshots
N/A — all evidence is in the GitHub Actions run logs and PR comment history (private repository).
Workflow yml file
name: Claude Code Review
on:
pull_request:
types: [opened, synchronize]
jobs:
claude-review:
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: read
issues: read
id-token: write
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 1
- name: Run Claude Code Review
id: claude-review
uses: anthropics/claude-code-action@v1
with:
claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
prompt: |
REPO: ${{ github.repository }}
PR NUMBER: ${{ github.event.pull_request.number }}
Please review this pull request and provide feedback on:
- Code quality and best practices
- Potential bugs or issues
- Performance considerations
- Security concerns
- Test coverage
Use the repository's CLAUDE.md for guidance on style and conventions.
Use `gh pr comment` with your Bash tool to leave your review as a comment on the PR.
claude_args: '--allowed-tools "Bash(gh issue view:*),Bash(gh search:*),Bash(gh issue list:*),Bash(gh pr comment:*),Bash(gh pr diff:*),Bash(gh pr view:*),Bash(gh pr list:*)"'API Provider
[x] Anthropic First-Party API (default) — using claude_code_oauth_token
Additional context
- Claude Code version (from leaked terminal output in one of the errant comments):
v2.1.23 - Model: Sonnet 4.5 · Claude Max
- Workflow run duration: 07:45:15–08:04:38 UTC (19 minutes)
- The errant comments appeared between 07:55–08:03 UTC, during the run
- Workflow run ID:
22131065397 - At least 9 different approaches to posting the comment were attempted before the file dumps occurred (direct
--body, heredoc to temp file, heredoc to workspace file, Python stdin redirect, Python triple-quoted string, Node.js one-liner, base64 decode,gh apidirect POST — all visible in the run logs) - Repository is private — no public exposure occurred; content was only visible to collaborators
- No credentials were exposed; the leaked database-reference.md has passwords redacted internally
Suggested fix: Add a --no-file-tools preset for CI/CD contexts that disables Read/Write/Grep/Glob regardless of claude_code_oauth_token vs claude_api_key mode, and recommend gh pr comment --body-file /tmp/review.md instead of inline --body in all documentation examples.