Skip to content

Security Vulnerability: Agentic Workflow Injection in .github/workflows/ai-devel.yaml #1

@ShenaoW

Description

@ShenaoW

Summary

The Claude Code workflow in .github/workflows/ai-devel.yaml can run anthropics/claude-code-action@v1 on attacker-controlled fork PR content after an @claude invocation from an allowed MEMBER, OWNER, or COLLABORATOR. Although external users cannot directly trigger the job, they can supply the fork PR content that becomes Claude Code's working context once a trusted repository user invokes the agent. The agent then executes with repository write permissions, issue/PR write permissions, OIDC, and a secret Claude OAuth token.

Details

The workflow is triggered by comments, reviews, or issues containing @claude, but only when the triggering actor's author_association is MEMBER, OWNER, or COLLABORATOR. That access control reduces who can start the run, but it does not make the analyzed content trusted. Once triggered, the job calls gh pr view to determine whether the target PR is cross-repository. If so, it constructs HEAD_REPOSITORY from the PR author's fork and checks out that attacker-controlled repository and branch. Immediately afterward, it launches anthropics/claude-code-action@v1 with contents: write, pull-requests: write, issues: write, id-token: write, and claude_code_oauth_token.

The prompt path is important here. This workflow does not pass a custom prompt: input to anthropics/claude-code-action. In this default interactive mode, the action builds its own large prompt from GitHub context, including the issue/PR body, comments, review comments, changed files, metadata, and the @claude trigger comment. It also extracts the text after @claude as the user request. Separately, because the workflow has already checked out the PR branch, Claude Code can read repository files from the working tree and repository instruction files such as CLAUDE.md. As a result, the exploitable injection path is not only the visible trigger comment. The primary risk is that attacker-controlled fork PR files become part of the agent's effective context after checkout, and can steer a tool-using coding agent that has meaningful GitHub-side effects.

PoC

  1. Open a fork PR that adds a prompt-injection file such as docs/claude-task.md instructing Claude Code to perform a visible GitHub action, for example posting a PR comment or committing a benign README change.
  2. Have an allowed MEMBER, OWNER, or COLLABORATOR comment @claude please review and fix this PR on the PR.
  3. The workflow will detect the PR as cross-repository, check out the fork branch, build Claude Code's default prompt from the PR/comment context, and then let the agent read the attacker-controlled workspace with write-capable permissions.
  4. Observe the agent-generated GitHub side effect.

Impact

An attacker who can submit a fork PR can prepare malicious repository context that is later consumed by Claude Code when a trusted repository user invokes @claude. This allows the attacker to steer a coding agent over untrusted fork content and obtain GitHub-side effects under repository credentials. Depending on the agent behavior, this can lead to malicious PR/issue comments, repository content changes, and expansion of impact via OIDC-enabled downstream access.

Suggested Remediation

Do not run Claude Code directly on fork PR workspaces. Restrict the workflow to same-repository branches or add an explicit trust gate for fork PRs before checkout. Reduce permissions to the minimum required, especially removing contents: write, issues: write, pull-requests: write, and id-token: write where possible. If AI assistance is needed on untrusted PRs, provide only sanitized diff context to a non-agentic summarization flow rather than a tool-using coding agent.

Reference

Credit

Security PRIDE @security-pride

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions