Hijacked GitHub accounts pushed a CI secret stealer into thousands of repos: am I affected?
Starting November 10, 2026, an attacker used stolen GitHub credentials to push a secret-stealing payload, which names itself wfx, into repositories those accounts could write to. Aikido Security counted 4,837 compromised accounts opening probe pull requests titled "docs: dependency audit notes" in 61,764 repositories, and found signs the payload ran in at least 1,806 of them. SafeDep counted 8,093 repositories that received malicious commits between November 10 at 12:46 UTC and November 12 at 04:36 UTC. The payload steals GitHub Actions secrets, cloud credentials and AI tool keys, and one variant runs on any npm install.
What was reported
Am I affected: check any repository you can write to for a wfx-docs branch, a pull request titled docs: dependency audit notes, a short-lived branch named chore/ followed by eight characters, or commits titled ci: refresh build cache, chore: add ci helper or chore: add dependency audit workflow on or after November 10, 2026.
Do now: if you find one, revoke the commit author's tokens, OAuth app grants, SSH keys and sessions, turn on 2FA, and rotate every secret and variable the repository can read. If anyone ran npm install on an affected commit, treat that machine as compromised too.
What the researchers found
Aikido Security says that starting at about 12:45 UTC on November 10, 2026, a threat actor used stolen GitHub credentials to push a malicious workflow payload that steals GitHub Actions secrets and cloud credentials. Based on the data it had collected:
- 4,837 compromised accounts opened probe pull requests in 61,764 repositories.
- 10,431 of those pull requests went into repositories the account doesn't own, reached through collaborator or organization access, and 92% were still open when Aikido checked.
- It found signs the payload ran in at least 1,806 repositories, and says that number may understate impact. (The post's summary list says at least 1,835 repositories ran the payload and have had credentials exfiltrated.)
- At least 50 of the compromised users appear to publish packages for npm, Go, Packagist, PyPI or crates.
Aikido also says a GitHub search returns 61,839 pull requests titled docs: dependency audit notes, opened between November 10 at 12:45 UTC and November 11 at 15:00 UTC. It says that pull request only confirms write access, and that an account that opened one is compromised even if the payload never ran. It says the attacker then pushes the payload in one of three ways: about 1,500 lines added to an existing workflow (ci: refresh build cache), a .ci-xxxxxx.sh script plus a postinstall hook in package.json that runs it on any npm install (chore: add ci helper), or a new workflow file on a short-lived chore/ branch (chore: add dependency audit workflow). The attacker then reverts the change and deletes the workflow run and its logs, so a missing run number in the workflow's history is often the only trace.
SafeDep counted 8,093 repositories that received malicious commits between November 10 at 12:46 UTC and November 12 at 04:36 UTC, and says the campaign was still active when that search ran. Its search covered only the default branches of public repositories, so it says the true total is higher. In 7,309 of them the payload was added to an existing workflow, in 771 it came as the npm postinstall hook, and in 16 an empty repository received a new workflow file. Aikido says the payload has settings for private repositories, which suggests it may be running in private repositories too. SafeDep's own GitHub search, separate from the 8,093 commit count, shows 61,879 of the probe pull requests in 61,734 repositories, opened from 4,833 accounts, with 91% still open.
What the payload takes
Aikido says the script collects GitHub Actions secrets and variables, the workflow's GITHUB_TOKEN, OIDC and Actions runtime tokens, credential files for AWS, Azure, GCP, Docker, Kubernetes, npm, PyPI, Git and SSH, and credentials for AI providers and AI developer tools including OpenAI, Anthropic, Gemini, Hugging Face, Cursor, Copilot and Codex. It also searches for .env files under the home directory and reads the memory of the runner's processes.
It then tries to go deeper and to outlast a rotation, according to Aikido: it exchanges GitHub OIDC tokens for AWS, GCP and Azure sessions, creates long-lived AWS access keys for IAM users, can rewrite an AWS role's trust policy to open it to any AWS account, and adds federated identity credentials named wfx-ci-… to Azure AD applications. Aikido also says it posts forged success status checks using the names of the repository's required checks, which clears branch protection merge gates. SafeDep says the payload has code to mark required status checks as passing, and that no sample it analyzed had that switched on.
SafeDep says three packages, on Packagist and the Go module proxy, shipped the payload, and that a scan of 218 npm, Go and Packagist packages whose source repositories received malicious commits found no other published version with it. PyPI and other registries were not checked.
What to do
SafeDep's advice for a repository that was hit:
- Revoke the commit author's tokens, OAuth app grants, SSH keys and sessions, and turn on 2FA. That account is the likely entry point.
- Rotate every secret and variable the repository can read, including environment and organization secrets, and any key the runner could reach.
- Delete the
wfx-docsbranch and close the probe pull request. - Pull any package version built between the malicious commit and the
ci: cleanupcommit, and publish again from a clean commit. - If someone ran
npm installon an affected commit, treat that machine as compromised and rotate its keys. - Check your cloud accounts for backdoors: Entra ID federated credentials named
wfx-ci-*that you did not create, and in AWS CloudTrail,AssumeRoleWithWebIdentityorAssumeRolesessions namedwfx-*followed byCreateAccessKeyorUpdateAssumeRolePolicy. SafeDep also says to check GCP forGenerateAccessTokenandSignJwtcalls from your GitHub workload identity pool, and Vault for JWT logins from the GitHub OIDC issuer.
Aikido says the absence of wfx-loot artifacts, wfx- cache entries or WFX-BEGIN step summaries does not mean data was not taken. Our advice: rotate AI provider keys (OpenAI, Anthropic and similar) at the provider even if your workflows only used them for tests, and check their usage pages for spend you don't recognize.
How to prevent it
Check every repo you can write to for a wfx-docs branch or a "docs: dependency audit notes" pull request. If you find one, treat the account that opened it as compromised: revoke its tokens, OAuth app grants, SSH keys and sessions and turn on 2FA, then rotate every secret and AI key that repo's workflows could read. Our advice: give workflows only the secrets they need and prefer short-lived OIDC credentials over stored keys.
Sources
- Aikido Security, wfx-loot campaign pushes CI secret stealer to tens of thousands of repositories (Nov 12, 2026)
- SafeDep, wfx: GitHub Actions Credential Stealer Hits 8,000 Repos (Nov 12, 2026)
Related
Incidents on the same topics
The weekly fix
The weekly fix: 3 real security mistakes in vibe-coded apps and how to fix them, every Tuesday.