GhostAction: pushing a malicious workflow into tens of thousands of repos
Attackers hijacked maintainer accounts and injected GitHub Actions workflows disguised as security audits that scrape credentials out of the entire git history. By 9 October, 500+ accounts and tens of thousands of repos were involved.
Attackers do not need to break into your CI. They need one trusted account to push one file. That is the GhostAction play.
How the attack moved
StepSecurity’s write-up gives two concrete cases:
- First, the account of Takashi Kitao — author of the game engine pyxel, a project with 18,400 GitHub stars — was compromised. From 13:20 UTC the attacker used it to push malicious workflows to 27 repositories.
- Eight hours later, the account of Henry Wu (henrywoo), original author of Uber’s open-source athenadriver, was compromised. In a 16-minute window from 21:10 to 21:26 UTC the attacker pushed the same workflow to 318 repositories.
By 9 October 2026, monitoring by the security firm Socket showed that since the campaign entered a wider spread on 7 October, more than 500 GitHub accounts had committed that workflow to tens of thousands of repositories.
This is not a new campaign either. GhostAction first surfaced in September 2025, hitting 817 repositories under 327 user names and stealing 3,325 sets of credentials.
What the workflow looks like
The files pushed by the two compromised accounts are named:
security-audit.yml, workflow name Security Auditgithub_actions_security.yml, workflow name GitHub Actions Security
The name is the disguise — a security audit sounds like something you would open on purpose.
It triggers on workflow_dispatch and on an unfiltered push (any branch, any tag). Once running it fetches everything with fetch-depth: 0 and executes a single step called Audit that does four things:
- Append the repository’s named secrets found during reconnaissance.
- Scan the working directory against 13 credential patterns.
- Scan the entire git history with the same patterns, for credentials that were deleted but still live in history.
- Automatically pair AWS access key IDs with their secret keys into a usable credential set.
Exfiltration goes over plaintext HTTP to the IP 193.32.204.199.
Why git history is the point
Step 3 is the most valuable part of the chain.
Most people remove a secret by committing a new revision that drops it. But git keeps the old revision. Scan the history and you recover what you thought was cleaned up long ago.
“Deleted” and “gone” are not the same thing in git.
A GitGuardian report published the same week gives a wider count: between 31 August and 30 September 2026, GhostAction pushed the workflow to 772 public repositories under 373 users and organisations, targeting 2,577 credentials — SSH private keys, Azure credentials, container registry credentials, database credentials, FTP, Google Cloud and Firebase, GitHub tokens, and Telegram, Slack and Discord bot tokens.
The spread path: forks
Socket notes an easily missed detail: 279 forks under the henrywoo namespace all carry the workflow.
So the exposure is not limited to the original repositories. If a fork has Actions enabled, any subsequent push triggers the credential theft. Private forks and downstream mirrors carry the highest risk, because private repositories tend to hold credentials that actually work.
What to do now
If your repositories have seen pushes in this window, the order I would follow:
- In commits after 31 August 2026, look for the filenames
security-audit.ymlandgithub_actions_security.yml. - Finding either means compromise: revoke GitHub credentials and rotate every related key immediately.
- Remove the malicious workflow from all branches, not just the default one.
- Check every fork of the affected repositories.
Step 3 is the one people skip: clean only the default branch and the workflow is still sitting on the others.
My take
The core issue is not that GitHub Actions is insecure. It is that the trust relationship between an account and a repository is far too wide.
Compromise one account and it can push to every repository it can reach; land a workflow and it inherits that repository’s secrets and its whole git history. The attacker really only needs to break one thing: a personal access token.
So the reduction that matters is not reading YAML more carefully. It is splitting publishing rights: least-privilege tokens for workflows, production secrets out of repository secrets, and write protection on the default branch. None of this is new. It just got proved worth doing again.

Comments
…