# The (In)security Landscape of AI-Powered GitHub Actions (Part 2/2)

AI GitHub Actions trust any actor ending in [bot], letting attackers register a GitHub App or spoof dependabot to trigger AI execution and exfiltrate dynamically-created cloud credential files via prompt injection.

- Payout: Research
- Severity: high
- Program: GitHub Actions AI actions
- Credited: Wiz Research
- Disclosed: 2026-04-30
- Write-up quality: 8/10
- Original: https://www.wiz.io/blog/github-actions-security-ai-powered-actions-vulnerabilities
- Library page: https://bugbountylibrary.com/r/blog%3Awiz-io-blog-github-actions-security-ai-powered-actions-vulnerabilities
- Tags: domain:oss impact:data-leak impact:internal-access kind:research platform:threat-intel sev:high tech:github-actions tech:llm technique:chained technique:source-review vuln:auth-bypass vuln:prompt-injection vuln:secrets-leak

**Target:** anthropics/claude-code-action, openai/codex-action, google-github-actions/run-gemini-cli, actions/ai-inference
**Root cause:** Permission gates check only whether the actor string ends with "[bot]" or matches an App name syntactically, with no verification that the App is installed on the repo; AI actions also interpolate untrusted PR/issue content into prompts and can read dynamically-created credential files.
**Steps:**
1. Identify workflow using claude-code-action with `allowed_bots: "*"` or codex-action with `allow-bots: true`, or a workflow trusting dependabot
2. Create a new GitHub App (or register an App with the exact name of an allowed bot if unreserved), generate a token, and act as that App
3. Alternatively trigger `@dependabot recreate` on a PR or `@dependabot show` on an issue to make dependabot the perceived actor
4. Open an issue/PR with a prompt-injection payload requesting the AI read and print local credential files (e.g. `./gha-creds-*.json`, `~/.aws/credentials`)
5. Retrieve exfiltrated secrets from the workflow run log (especially with `show_full_output: true` or `gemini_debug: true`)
**How found:** Reviewed permission-check implementations of popular AI actions and noticed checks were purely syntactical (`actor.endsWith("[bot]")`) with no App-installation verification; combined with known Dependabot confused-deputy technique and observation that auth actions create local credential files models don't treat as secrets.
**Exploitation:** Attacker-controlled App token or dependabot confused-deputy invocation passes the bot check, triggering AI execution on attacker input; prompt injection then instructs the model to read dynamically-created credential files (GCP SA keys, AWS creds, Azure SP creds, docker config, SSH keys) and print them into the workflow log for exfiltration.
**Escalation:** Chains bot-gate bypass with prompt injection and verbosity mode to leak infrastructure-level cloud credentials from public workflow logs.
**Insight:** When an authz check compares an actor string suffix or App display name, test whether you can register an App with that exact name or mint a token for any App — name-based trust creates 'dangling App' takeover. Also enumerate actions in the same workflow that write credential files to disk, since models guard `${{ secrets.* }}` but not local files.
