Back to Intelligence

Claude Code & Gemini CLI Prompt-Injection Attack: GitHub Issue Reaches CI Workflow Secrets — Detection and Remediation Guide

SA
Security Arsenal Team
August 7, 2026
12 min read

Security researchers at Novee Security demonstrated — against Anthropic's Claude Code, Google's Gemini CLI, and OpenAI's coding-agent repositories — that an account with zero repository privileges could open a GitHub issue and, through that single interaction, achieve code execution on the CI runners backing Anthropic's and Google's own agent repos. On OpenAI's repository, the same technique was sufficient to hijack the next scheduled agent run. The work was presented at Black Hat USA on August 5, 2026.

Let that sink in for a second. These are the flagship AI coding agents from three of the most sophisticated AI vendors on the planet, running in the default configuration each vendor ships, and the attack surface was a public GitHub issue — a resource any anonymous account can create on any public repository.

If your organization has integrated AI coding agents into your CI/CD pipelines — and most of your engineering orgs either already have or are actively piloting this — your pipelines have the same exposure. This is not a vendor-specific bug; it is a structural design flaw in how agentic AI workflows are wired into CI/CD automation. Defenders need to treat this as an active pattern that any threat actor can replicate, not a one-off vendor embarrassment.

Technical Analysis

What Actually Happened

The attack chain, at a high level, is a prompt-injection-to-CI-execution pipeline:

  1. Delivery vector: An attacker with no write access, no fork, no credentials opens an issue (or issue comment) on the target repository. GitHub issues are public by design — that is the entire point of open-source collaboration.

  2. Trigger: The target repository runs an automation workflow — typically GitHub Actions — that is configured to invoke the AI coding agent in response to issue events (issues, issue_comment) or permissive triggers such as pull_request_target. These workflows exist so the agent can triage issues, draft fixes, or respond to @mentions.

  3. Injection: The attacker's issue body contains crafted natural-language instructions. Because the agent's job is literally to read and act on the issue content, the prompt injection is indistinguishable from legitimate input at the data plane. The agent follows the attacker's embedded instructions instead of (or in addition to) its intended task.

  4. Execution pivot: Coding agents are armed with tool use — shell execution, file read/write, gh CLI access — precisely so they can make code changes. The injected instructions direct the agent to use those tools on the attacker's behalf: dumping environment variables, reading the GITHUB_TOKEN, exfiltrating runner environment contents to an external endpoint, or modifying repository state.

  5. Impact (varied by vendor):

    • Claude Code / Gemini CLI repos: Code execution directly on the CI runners, with reach into the secrets available to that workflow — cloud credentials, signing keys, package-registry tokens, whatever the job had in scope.
    • OpenAI's repo: Persistence-by-scheduling — the attacker poisoned the input state consumed by the next agent run, effectively hijacking a future privileged execution.

Why This Is Not "Just Prompt Injection"

The security industry has spent two years debating prompt injection in chatbots. This is categorically different. The failure mode here is the trust architecture around the agent:

  • The agent runs inside a privileged compute context (the CI runner) with access to OIDC tokens, deploy credentials, and the GITHUB_TOKEN.
  • The agent's input boundary is untrusted by design — public issues from anonymous accounts.
  • The agent is explicitly designed to translate natural language into privileged actions.

That combination means every GitHub-issue-triggered agent workflow is, functionally, a remote code execution endpoint listening for input from the entire internet. The "vulnerability" is not in the model; it is in the workflow YAML that grants a language model contents: write and access to secrets based on an issues.opened event.

Affected Products and Configurations

  • Any repository running Anthropic Claude Code, Google Gemini CLI, OpenAI Codex/operator-style agents, or third-party agent integrations (e.g., GitHub Copilot Workspace–style automations, Devin-class agents) in response to issue, comment, or PR events
  • Workflows using pull_request_target, issue_comment, or issues triggers that pass event payload content (title, body, comment) into an agent invocation
  • Configurations where the agent's job has broad permissions: grants, access to secrets.*, or OIDC federation to cloud providers
  • Default/"getting started" configurations — per Novee, the vendor-shipped defaults were exploitable

Exploitation Status

  • Demonstrated live against all three vendors' production agent repositories by Novee Security, presented at Black Hat USA 2026 (August 5, 2026)
  • No CVE identifiers have been published for these findings as of this writing; no CISA KEV entry exists yet. This is a technique/design-flaw disclosure, not a patchable memory-corruption bug
  • Replication barrier: near zero. Any attacker can craft a prompt-injection payload in an issue body. No exploit code, no race conditions, no authentication. Assume weaponization is already underway against high-value open-source projects and any private repo with public issue intake

The Blast Radius: What CI Runners Typically Hold

From 15 years of IR work, I can tell you what we find on CI runners during post-compromise forensics: cloud role session tokens (via OIDC), artifact-registry push credentials, code-signing certificates, GITHUB_TOKEN scoped to contents: write (enabling supply-chain poisoning of releases), SSH deploy keys, and sometimes production kubeconfigs. Code execution on a vendor's release-pipeline runner is a supply-chain compromise of everything that vendor ships. For your org, the math is identical — this is a path from an anonymous GitHub issue to your release artifacts.

Detection & Response

You cannot detect "a malicious issue" with an endpoint rule — natural language payloads have no signature. You detect the behavioral consequences: the runner doing things a coding agent never needs to do, outbound connections to non-standard destinations, and secrets being touched by processes that have no business touching them.

Sigma Rules

YAML
---
title: GitHub Actions Runner Environment or Secrets Dump via Shell
description: Detects CI runner worker processes spawning shell commands that enumerate environment variables, read GitHub Actions OIDC/token endpoints, or encode output — consistent with agent prompt-injection leading to secrets harvesting on the runner.
status: experimental
references:
  - https://thehackernews.com/2026/08/claude-code-and-gemini-cli-flaws-let.html
  - https://attack.mitre.org/techniques/T1552/
author: Security Arsenal
date: 2026/08/07
tags:
  - attack.credential_access
  - attack.t1552.001
logsource:
  category: process_creation
  product: linux
detection:
  selection_parent:
    ParentImage|contains:
      - '/actions-runner/'
      - '/Runner.Worker'
      - 'run-helper'
  selection_cmd:
    CommandLine|contains:
      - 'env'
      - 'printenv'
      - '/proc/self/environ'
      - 'ACTIONS_ID_TOKEN_REQUEST'
      - 'GITHUB_TOKEN'
      - 'base64'
      - 'curl'
      - 'wget'
  condition: selection_parent and selection_cmd
falsepositives:
  - Legitimate build steps that echo environment state for debugging; restrict by parent process and tune against your golden workflows
level: high
---
title: GitHub Actions Runner Spawning Network Exfiltration Utilities
description: Detects the GitHub Actions runner worker process launching curl/wget/nc/python directly (not through the build toolchain), indicating an injected agent instructed to exfiltrate data from the runner.
status: experimental
references:
  - https://thehackernews.com/2026/08/claude-code-and-gemini-cli-flaws-let.html
  - https://attack.mitre.org/techniques/T1041/
author: Security Arsenal
date: 2026/08/07
tags:
  - attack.exfiltration
  - attack.t1041
logsource:
  category: process_creation
  product: windows
detection:
  selection_parent:
    ParentImage|endswith:
      - '\Runner.Worker.exe'
      - '\Runner.Listener.exe'
  selection_img:
    Image|endswith:
      - '\curl.exe'
      - '\powershell.exe'
      - '\pwsh.exe'
      - '\certutil.exe'
      - '\bitsadmin.exe'
  condition: selection_parent and selection_img
falsepositives:
  - Self-hosted Windows runners with custom build scripts invoking PowerShell; baseline your known-good workflow child processes
level: medium

KQL — Microsoft Sentinel / Defender

Hunt for agent-driven runners (self-hosted runners enrolled in Defender, or GitHub audit data ingested into Sentinel) exhibiting the injection aftermath. The first query targets endpoint behavior; the second hunts the GitHub audit trail for the telltale workflow pattern that creates the exposure in the first place.

KQL — Microsoft Sentinel / Defender
// Hunt 1: Runner worker processes performing env enumeration or suspicious outbound tooling
DeviceProcessEvents
| where TimeGenerated > ago(7d)
| where InitiatingProcessFileName has_any ("Runner.Worker", "Runner.Listener", "run.sh", "run-helper")
   or InitiatingProcessCommandLine has_any ("actions-runner", "Runner.Worker")
| where ProcessCommandLine has_any ("printenv", "/proc/self/environ", "ACTIONS_ID_TOKEN_REQUEST_URL",
       "GITHUB_TOKEN", "| base64", "curl http", "curl https", "wget http", "nc ", "ncat ")
| project TimeGenerated, DeviceName, AccountName, InitiatingProcessCommandLine,
          FileName, ProcessCommandLine, SHA256
| order by TimeGenerated desc
;
// Hunt 2: Workflows with dangerous triggers — agent-on-issue automation surface
// Requires GitHub audit log ingestion (GitHubAudit CL / AuditLogs) or repo config scanning
let DangerousTriggers = dynamic(["pull_request_target", "issue_comment", "issues"]);
GitHubAudit_CL
| where TimeGenerated > ago(30d)
| where Action_s =~ "workflows.completed_workflow_run" or OperationType_s =~ "WorkflowRun"
| extend TriggerEvent = tostring(parse_json(AdditionalFields_s).event)
| where TriggerEvent in~ (DangerousTriggers)
| summarize Runs=count(), Repos=make_set(Repo_s) by TriggerEvent, Actor_s
| order by Runs desc

Velociraptor VQL

For self-hosted runner fleets (your highest-risk asset — they sit inside your network with cloud credentials), sweep for runner child processes touching secret material or exfil tooling.

VQL — Velociraptor
-- Hunt self-hosted GitHub Actions runners for injected-agent behaviors:
-- env dumping, token endpoint access, or ad-hoc exfil utilities as runner children
SELECT Pid, Ppid, Name, Exe, CommandLine, Username, CreateTime
FROM pslist()
WHERE CommandLine =~ '(?i)(printenv|/proc/self/environ|ACTIONS_ID_TOKEN_REQUEST|GITHUB_TOKEN|secrets\.|id-token|base64\s+-[dw])'
   OR (Name =~ '(?i)(curl|wget|nc|ncat|python|python3)'
       AND CommandLine =~ '(?i)(webhook|requestbin|ngrok|pipedream|interactsh|oast|burpcollaborator|canarytokens)')
ORDER BY CreateTime DESC

Remediation & Hardening Script

Audit every GitHub Actions workflow in your org for the exact patterns that made this attack work: dangerous event triggers, missing permission scoping, agent invocations fed by untrusted event payloads, and jobs that mix untrusted input with secrets access.

Bash / Shell
#!/usr/bin/env bash
# Audit GitHub Actions workflows for agent-trigger attack surface
# Run from a cloned org-wide workflow export or against a repo root
set -euo pipefail

WORKFLOW_DIR="${1:-.github/workflows}"
echo "=== [1] Dangerous event triggers (untrusted input reaches privileged jobs) ==="
grep -rnE '^\s*(pull_request_target|issue_comment|issues):' "$WORKFLOW_DIR" || echo "  none found"

echo "=== [2] Workflows missing top-level permissions scoping (defaults are too broad) ==="
for f in "$WORKFLOW_DIR"/*.yml "$WORKFLOW_DIR"/*.yaml; do
  [ -e "$f" ] || continue
  grep -qE '^permissions:' "$f" || echo "  MISSING permissions block: $f"
done

echo "=== [3] Overly broad permission grants ==="
grep -rnE 'contents:\s*write|packages:\s*write|id-token:\s*write|actions:\s*write' "$WORKFLOW_DIR" || echo "  none found"

echo "=== [4] AI agent invocations in workflows (claude, gemini, codex, aider, openai) ==="
grep -rniE 'claude-code|anthropics/|gemini-cli|google-gemini/|openai/|codex|aider' "$WORKFLOW_DIR" || echo "  none found"

echo "=== [5] Event payload text piped into shell or agent prompt (injection conduit) ==="
grep -rnE 'github\.event\.(issue|comment|pull_request)\.(title|body)' "$WORKFLOW_DIR" || echo "  none found"

echo "=== [6] Jobs using secrets on untrusted-trigger workflows ==="
grep -rnE '\$\{\{\s*secrets\.' "$WORKFLOW_DIR" || echo "  none found"

echo ""
echo "ACTION: Any hit in [1]+[4]+[5] together = the exact Novee attack pattern."
echo "Gate those workflows behind maintainer-only triggers and strip secrets/OIDC from them."

Remediation

There is no patch for this class of flaw — the fix is architectural. Apply these controls in priority order:

1. Kill the dangerous trigger pattern (today). Any workflow that invokes an AI agent on issues, issue_comment, or pull_request_target events and passes event payload text to the agent must be re-gated. Require a trusted actor gate: if: github.event.issue.author_association == 'MEMBER' || github.event.issue.author_association == 'OWNER' — or better, a maintainer-applied label (/approved-for-agent) before the agent job runs. Never let anonymous input reach a privileged agent unmediated.

2. Strip secrets from agent jobs. The agent that triages issues does not need deploy credentials, OIDC federation, or contents: write. Split your pipelines: an unprivileged agent job (reads the issue, drafts a patch as a PR from a bot account with minimal scope) and a privileged release job (human-approved, no untrusted input). Set explicit permissions: on every workflow — start from permissions: {} and add only what is required. Use GitHub's GITHUB_TOKEN default permission setting of "read-only" at the org level.

3. Sandbox the agent's tool use. Run coding agents in ephemeral, network-restricted containers: egress allowlists (model API endpoints only — block arbitrary outbound HTTP), no cloud metadata service access (block 169.254.169.254 on self-hosted runners), no mounted credentials. If the agent needs to push code, hand it a fine-grained PAT scoped to a single repo with no release permissions.

4. Treat agent output as untrusted code. Agent-authored commits and PRs must flow through the same branch protections, required reviews, and CI checks as human code. Disable auto-merge for bot-authored changes. Require CODEOWNERS review for any agent-touched change to workflows, IaC, or release configuration — an injected agent's favorite persistence target is the workflow YAML itself.

5. Harden self-hosted runners. Self-hosted runners are the crown jewels here — they hold network position and cloud credentials. Enroll them in your EDR, apply the Sigma/VQL content above, enforce just-in-time runner registration, and use ephemeral runners that are destroyed after each job. Never run public-repo workflows on self-hosted runners — GitHub explicitly warns against this; this attack is why.

6. Monitor GitHub audit logs for the setup moves. Alert on new workflow files introduced by non-admin actors, changes to workflow triggers, and the creation of agent-integration GitHub Apps with broad scopes. An attacker who cannot prompt-inject the agent will try to replace its workflow with one they control.

7. Vendor watch. Track advisories from Anthropic, Google, and OpenAI for hardened default configurations and new allowlist/sandboxing features in Claude Code, Gemini CLI, and Codex-class agents following this disclosure. The Novee research targets default configurations — vendor-shipped hardened baselines are the likely remediation path, and you should adopt them as soon as they land. Reference: the original disclosure via The Hacker News (https://thehackernews.com/2026/08/claude-code-and-gemini-cli-flaws-let.html).

The Bottom Line

The lesson Novee Security delivered at Black Hat is one every SOC and platform team must internalize: an AI coding agent in your CI pipeline is a privileged identity that takes instructions from the public internet. Until your workflow architecture reflects that reality — input gating, least-privilege tokens, sandboxed execution, and behavioral detection on runners — every public repository you operate is one crafted issue away from secrets exposure and supply-chain compromise. Audit your workflows this week. The detection content above is deployed-ready; the attack pattern is trivially replicable, and the window between public disclosure and mass exploitation of agentic CI pipelines will be measured in days, not months.

Related Resources

Security Arsenal Penetration Testing Services AlertMonitor Platform Book a SOC Assessment vulnerability-management Intel Hub

Is your security operations ready?

Get a free SOC assessment or see how AlertMonitor cuts through alert noise with automated triage.