GitHub Actions GhostAction campaign returns to steal secrets

The GhostAction campaign is back. Hijacked GitHub maintainer accounts are pushing workflows that steal Actions secrets and every credential ever committed to a repository's history. Deleting a leaked key from the current code no longer protects you: if it is anywhere in git history, rotate it.

What happened

StepSecurity reported on October 9, 2026 that two maintainer accounts were used on October 8 to push malicious workflows. Takashi Kitao's account (kitao, author of the pyxel game engine) touched 27 repositories between 13:20 and 13:44 UTC. Henry Wu's account (henrywoo, original author of Uber's athenadriver) touched 318 repositories, 39 source repos and 279 forks, between 21:10 and 21:26 UTC. StepSecurity also names xxyangyoulin as an earlier compromise that is still active. By October 9, GitHub code search showed 378 repositories with a live malicious workflow on the default branch.

The workflows are named security-audit.yml, github_actions_security.yml or security-check.yml and trigger on workflow_dispatch and unfiltered push. The October variant does two things. It packs the repo's named Actions secrets into its payload. It also checks out full history and runs git log -p --all, then greps for 13 credential types, including AWS access keys, Anthropic, OpenAI and OpenRouter keys, GitHub PATs, and GitLab, Google/Firebase, Slack and SendGrid tokens. Everything goes out in a single plaintext HTTP POST to 193.32.204.199.

StepSecurity confirmed a malicious run on uber/athenadriver at 21:26:04 UTC on October 8 that fetched all 13 branches and 20 tags, with the C2 acknowledging receipt. On pyxel, manual re-dispatches showed hands-on-keyboard activity. The original GhostAction wave in September 2025 hit 817 repositories. StepSecurity dates use of the current C2 to September 4, 2026.

Counts vary by source. The Hacker News cites Socket as finding more than 500 accounts pushing these workflows and "tens of thousands" of repositories, and GitGuardian as reporting 772 public repos between August 31 and September 30. Use StepSecurity's 345 as the confirmed figure for the October 8 pushes, not the size of the whole campaign.

Why it matters

This is a non-human identity breach that starts with a human account. One maintainer's GitHub credential gave the attacker write access to hundreds of repos, and from there every pipeline secret and every key committed in the past. The history sweep is the new part, and it widens the cleanup: a key removed from the code years ago but never rotated is now exposed.

The control that worked is simple. On typecho-fans/plugins, a required approval for workflow runs left the malicious run stuck in action_required, and nothing was exfiltrated. Unlike our Tensorlake npm coverage, which hit developer machines, this one runs in CI, so CI controls are what limit the damage.

What to check in your environment

  • Search all branches and forks for security-audit.yml, github_actions_security.yml and security-check.yml, plus commits titled "Add security audit workflow", "Update security audit workflow" or "Trigger security scan". StepSecurity notes that forks of infected repos carry the workflow.
  • Audit workflow runs since August 31, 2026 and check runner or egress logs for connections to 193.32.204.199 on ports 80 and 3000.
  • Rotate more than the current secrets. StepSecurity's guidance:
    Rotate everything the history sweep could reach: all Actions secrets, and every credential ever committed to any branch
    Scan your own history first so you know what that list contains.
  • Revoke the credential that did the push. Find and revoke the PAT or session behind the injected commits, not just the downstream secrets.
  • Delete the workflow from every branch, not only the default, and hold releases until cleanup is done if publishing secrets were configured.
  • Require approval for workflow runs and protect .github/workflows/* with branch protection that requires pull request review.
  • Restrict runner egress to an allowlist. A raw-IP, plaintext HTTP POST should not be able to leave a build runner.

References

Original source: StepSecurity