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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
Repository: zenstackhq/zenstack
Length of output: 3984
🌐 Web query:
GitHub Actionspull_request_targetsecurity risks forked pull requests secrets write permissions💡 Result:
Why
pull_request_targetis risky with forked PRspull_requestwould be blocked). (docs.github.com)actions/checkoutatgithub.event.pull_request.head.shaor otherwise runs code from the fork), you can end up running attacker-controlled code with secrets available, enabling secret exfiltration (“pwn request”) and follow-on compromise. (securitylab.github.com)GITHUB_TOKENmay have write capabilities unless you explicitly restrict it, so a compromised run can potentially push commits/tags, open/modify PRs, create releases, edit issues, etc. (depending on granted permissions). (synacktiv.com)The common “fork PR + secrets + write” failure mode
pull_request_targetworkflow triggers (base repo context).GITHUB_TOKENto persist changes (e.g., push to the repo, poison artifacts). (securitylab.github.com)Key mitigations (safe patterns)
pull_requestfor CI on code from forks (GitHub’s default safety model: no secrets + read-only token). (github.blog)pull_request_target(e.g., to comment/label):permissions:forGITHUB_TOKEN(avoid broad write). (github.blog)Recent platform change to be aware of
pull_request_target-related evaluation, but GitHub still emphasizes that usingpull_request_targetwith fork PRs remains inherently higher risk because it executes based on user-supplied PRs and can access secrets. (github.blog)Citations:
pull_request_targetwith untrusted PR checkout creates secret exfiltration riskLine 4 enables
pull_request_target, which runs this workflow with base-repository secrets and permissions. However, theactions/checkout@v4call (lines 30–32) does not specify a ref, causing it to check out the PR's head code (attacker-controlled). Combined with the availableCLAUDE_CODE_OAUTH_TOKENsecret andpull-requests: writepermission, this creates a direct path for secret exfiltration: a malicious PR could extract the token or abuse the write scope during the action's execution.Either switch to
pull_request(revokes secrets, read-only token) or apply all three mitigations ifpull_request_targetis mandatory:persist-credentials: falseto prevent untrusted code execution with secrets in scope.@betatag.GITHUB_TOKENpermissions further if possible.Hardening diff
- name: Checkout repository uses: actions/checkout@v4 with: + ref: ${{ github.event.pull_request.base.sha }} fetch-depth: 1 + persist-credentials: false - name: Run Claude Code Review id: claude-review - uses: anthropics/claude-code-action@beta + uses: anthropics/claude-code-action@<commit-sha> with: claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}🤖 Prompt for AI Agents