Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 44 additions & 0 deletions .github/workflows/claude-code-review.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
name: Claude Code Review

on:
pull_request:
types: [opened, synchronize, ready_for_review, reopened]
# Optional: Only run on specific file changes
# paths:
# - "src/**/*.ts"
# - "src/**/*.tsx"
# - "src/**/*.js"
# - "src/**/*.jsx"

jobs:
claude-review:
# Optional: Filter by PR author
# if: |
# github.event.pull_request.user.login == 'external-contributor' ||
# github.event.pull_request.user.login == 'new-developer' ||
# github.event.pull_request.author_association == 'FIRST_TIME_CONTRIBUTOR'

runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: read
issues: read
id-token: write

steps:
- name: Checkout repository
uses: actions/checkout@v4
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Look up the commit SHAs for the mentioned actions
echo "=== actions/checkout v4 ==="
git ls-remote https://github.com/actions/checkout refs/tags/v4 | head -5

echo ""
echo "=== anthropics/claude-code-action v1 ==="
git ls-remote https://github.com/anthropics/claude-code-action refs/tags/v1 | head -5

echo ""
echo "=== Checking if commit SHA for checkout v4.2.2 exists ==="
git ls-remote https://github.com/actions/checkout refs/tags/v4.2.2

Repository: libar-dev/delivery-process

Length of output: 364


🌐 Web query:

CVE-2025-30066 tj-actions changed-files March 2025 supply chain attack secrets

💡 Result:

What happened (March 2025)

  • tj-actions/changed-files (a widely used GitHub Action) was hit by a supply-chain compromise tracked as CVE-2025-30066. Attackers retagged many existing version tags (e.g., v1v45.x) to point to a malicious commit (notably `0e58ed8671d6b60d0890c21b07f8835ace038e67). The injected code fetched and ran a script intended to extract secrets from the GitHub Actions runner (Runner Worker) process memory and print them into workflow logs (often as double-base64 output). [1] [2] [3]

What “secrets” were exposed

  • Reported/possible exposed items include GitHub PATs, cloud access keys (e.g., AWS), npm tokens, and private keys (e.g., RSA)—basically anything present in runner environment/memory during the workflow run. [2] [1]

When it mattered (compromise window)

  • CISA’s guidance highlights investigating repos that ran tj-actions/changed-files during 2025-03-12 00:00 UTC to 2025-03-15 12:00 UTC. [1]
  • The GitHub advisory describes the vulnerability as active between March 14–15, 2025. [2]

Scope / who was at highest risk

  • Public repositories were at greatest risk because workflow logs are publicly readable, so leaked secrets could be harvested. Private repos still needed investigation because secrets may have been exposed to anyone with log access. [3] [2]

Patch / fixed version

  • GitHub’s advisory lists affected versions as <= 45.0.7 and a patched release 46.0.1. [2]
  • CISA also points to v46.0.1 as the patched version. [1]

Related compromise (likely enabling factor)

  • CISA reported the tj-actions/changed-files compromise may have been enabled by a compromise of reviewdog/action-setup@v1 (CVE-2025-30154) during March 11, 2025 18:42–20:31 UTC, potentially affecting other Reviewdog actions. [1]

What to do (practical response)

  1. Identify exposure: find repos/workflows that used tj-actions/changed-files in the window above and inspect the logs for suspicious/double-base64 blobs. [1] [2]
  2. Rotate secrets immediately (treat as compromised): PATs, cloud keys, npm tokens, SSH/RSA keys, etc. [1] [2]
  3. Update to tj-actions/changed-files@v46.0.1 (or later) and pin actions to immutable commit SHAs going forward. [1] [2]
  4. Check for suspicious outbound access to gist.githubusercontent.com (a key indicator noted in incident writeups) and other unexpected network destinations during workflow runs. [2] [3]

Sources: CISA alert and timelines [1], GitHub Advisory Database entry (GHSA-mrrh-fwg8-r2c3 / CVE-2025-30066) [2], StepSecurity incident analysis [3], Wiz incident analysis [4].

References

  • [1] CISA: Supply Chain Compromise of tj-actions/changed-files (CVE-2025-30066) and reviewdog/action-setup@v1
  • [2] GitHub Advisory Database: GHSA-mrrh-fwg8-r2c3 / CVE-2025-30066
  • [3] StepSecurity: Harden-Runner detection / incident write-up
  • [4] Wiz: tj-actions/changed-files supply chain attack analysis

Pin both actions to full-length commit SHAs to prevent supply-chain attacks.

Both actions/checkout@v4 and anthropics/claude-code-action@v1 use mutable version tags. If an attacker gains access to the account that publishes an action, they can commit malicious code and update existing Git tags to point to the new malicious commit — exactly what happened in March 2025 when tj-actions/changed-files was compromised, affecting more than 23,000 repositories. Attackers retagged multiple versions to point to a malicious commit that extracted secrets from the GitHub Actions runner environment.

Pinning an action to a full-length commit SHA is the only way to guarantee immutable release execution. This is critical here because the CLAUDE_CODE_OAUTH_TOKEN secret is in scope for both actions.

🔒 Proposed fix: pin both actions to commit SHAs
-        uses: actions/checkout@v4
+        uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5  # v4
-        uses: anthropics/claude-code-action@v1
+        uses: anthropics/claude-code-action@29214eeb6626cb5b6abf73a380c90ca849259729  # v1

Also applies to: 36-36

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/claude-code-review.yml at line 30, Update the workflow to
pin both actions to immutable full-length commit SHAs instead of mutable tags:
replace uses: actions/checkout@v4 and uses: anthropics/claude-code-action@v1
with their corresponding full 40-character commit SHAs; locate the two usages of
"actions/checkout@v4" and "anthropics/claude-code-action@v1" in the workflow and
substitute the tag with the exact commit SHA for each action (keeping the rest
of the step configuration unchanged) so the workflow runs a fixed, auditable
commit.

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 }}
plugin_marketplaces: 'https://github.com/anthropics/claude-code.git'
plugins: 'code-review@claude-code-plugins'
prompt: '/code-review:code-review ${{ github.repository }}/pull/${{ github.event.pull_request.number }}'
# See https://github.com/anthropics/claude-code-action/blob/main/docs/usage.md
# or https://code.claude.com/docs/en/cli-reference for available options

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Remove trailing blank line — YAMLlint reports this as an error.

🛠️ Proposed fix
           # See https://github.com/anthropics/claude-code-action/blob/main/docs/usage.md
           # or https://code.claude.com/docs/en/cli-reference for available options
-
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
# See https://github.com/anthropics/claude-code-action/blob/main/docs/usage.md
# or https://code.claude.com/docs/en/cli-reference for available options
🧰 Tools
🪛 YAMLlint (1.38.0)

[error] 44-44: too many blank lines (1 > 0)

(empty-lines)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/claude-code-review.yml at line 44, Remove the trailing
blank line at the end of the workflow file to satisfy YAMLlint: open the
claude-code-review GitHub Actions YAML (the workflow file) and delete the final
empty newline so the file ends with the last YAML mapping/sequence line (no
extra blank line), then save/commit the change; this will eliminate the YAMLlint
error about a trailing blank line.

50 changes: 50 additions & 0 deletions .github/workflows/claude.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
name: Claude Code

on:
issue_comment:
types: [created]
pull_request_review_comment:
types: [created]
issues:
types: [opened, assigned]
pull_request_review:
types: [submitted]

jobs:
claude:
if: |
(github.event_name == 'issue_comment' && contains(github.event.comment.body, '@claude')) ||
(github.event_name == 'pull_request_review_comment' && contains(github.event.comment.body, '@claude')) ||
(github.event_name == 'pull_request_review' && contains(github.event.review.body, '@claude')) ||
(github.event_name == 'issues' && (contains(github.event.issue.body, '@claude') || contains(github.event.issue.title, '@claude')))
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: read
issues: read
id-token: write
actions: read # Required for Claude to read CI results on PRs
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Fix inline comment spacing — YAMLlint expects two spaces before #.

🛠️ Proposed fix
-      actions: read # Required for Claude to read CI results on PRs
+      actions: read  # Required for Claude to read CI results on PRs
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
actions: read # Required for Claude to read CI results on PRs
actions: read # Required for Claude to read CI results on PRs
🧰 Tools
🪛 YAMLlint (1.38.0)

[warning] 26-26: too few spaces before comment: expected 2

(comments)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/claude.yml at line 26, The inline comment on the YAML key
"actions: read # Required for Claude to read CI results on PRs" needs proper
spacing for YAMLlint; insert two spaces before the hash so the line becomes
"actions: read  # Required for Claude to read CI results on PRs" to satisfy the
linter rule and preserve the comment text.

steps:
- name: Checkout repository
uses: actions/checkout@v4
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Pin both actions to full-length commit SHAs — same supply-chain risk as in claude-code-review.yml.

🔒 Proposed fix
-        uses: actions/checkout@v4
+        uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683  # v4.2.2
-        uses: anthropics/claude-code-action@v1
+        uses: anthropics/claude-code-action@<sha>  # v1 - resolve current SHA for the v1 tag

Also applies to: 35-35

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/claude.yml at line 29, Replace the floating tags for
GitHub Actions with full-length commit SHAs to eliminate supply-chain risk:
locate the "uses: actions/checkout@v4" entry and any other "uses:" entries in
this workflow (the second action referenced in the review), and change them to
pinned forms like "uses: actions/checkout@<full-commit-sha>" (and similarly
replace the other action's tag with its full commit SHA). Ensure you fetch the
canonical full-length SHA from the action's GitHub repository release/commit and
update both "uses" lines so neither uses a short tag (vX) or floating ref.

with:
fetch-depth: 1

- name: Run Claude Code
id: claude
uses: anthropics/claude-code-action@v1
with:
claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}

# This is an optional setting that allows Claude to read CI results on PRs
additional_permissions: |
actions: read
# Optional: Give a custom prompt to Claude. If this is not specified, Claude will perform the instructions specified in the comment that tagged it.
# prompt: 'Update the pull request description to include a summary of changes.'

# Optional: Add claude_args to customize behavior and configuration
# See https://github.com/anthropics/claude-code-action/blob/main/docs/usage.md
# or https://code.claude.com/docs/en/cli-reference for available options
# claude_args: '--allowed-tools Bash(gh pr:*)'

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Remove trailing blank line — YAMLlint reports this as an error, same as in claude-code-review.yml.

🛠️ Proposed fix
           # or https://code.claude.com/docs/en/cli-reference for available options
           # claude_args: '--allowed-tools Bash(gh pr:*)'
-
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
# or https://code.claude.com/docs/en/cli-reference for available options
# claude_args: '--allowed-tools Bash(gh pr:*)'
🧰 Tools
🪛 YAMLlint (1.38.0)

[error] 50-50: too many blank lines (1 > 0)

(empty-lines)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/claude.yml at line 50, Remove the trailing blank line at
the end of the GitHub Actions workflow file (.github/workflows/claude.yml) so
the file ends on the last YAML content line (matching the same fix applied to
claude-code-review.yml); open claude.yml, delete the final empty newline/blank
line after the last workflow key/step, and save so YAML linter no longer reports
the trailing blank-line error.

Loading