Since November 10, 2026, a credential-theft campaign that researchers call wfx (or wfx-loot) has been using compromised GitHub accounts to inject a malicious GitHub Actions payload into every repository those accounts can write to. Aikido counts 4,837 compromised accounts opening probe pull requests in 61,764 repositories. SafeDep counts 8,093 repositories that received malicious commits between November 10 12:46 UTC and November 12 04:36 UTC. Aikido and Endor Labs put confirmed payload execution, meaning credentials exfiltrated, at roughly 1,806–1,835 repositories, and both say that figure is probably low.
This is the third mass GitHub Actions secret-theft wave this year, after Megalodon in May and the GhostAction resurgence in October. Researchers report that accounts hit by GhostAction were much more likely to show up in wfx. That points to stolen PATs being reused, not to a new initial-access technique.
How the attack works
- Probe. The attacker opens a pull request titled
docs: dependency audit notesfrom a branch namedwfx-docsto confirm the hijacked account has write access. - Inject. On repos where it does, the attacker pushes a commit that adds or changes a workflow. Commit messages seen so far are
ci: refresh build cacheandchore: add ci helper. Branches matchchore/[a-z0-9]{8}orci-check-[0-9]{4}. - Harvest. The workflow dumps every Actions secret in scope, scrapes runner process memory to capture masked secrets (the same technique used in the tj-actions and issues-helper compromises), mints OIDC tokens, and collects secrets found in commit history. Targets include cloud credentials, package-registry publish tokens (npm, PyPI, Go, Packagist, crates.io), and AI provider keys (OpenAI, Anthropic, Hugging Face).
- Persist in the cloud. With AWS or Azure credentials in hand, the payload tries to survive rotation. Watch for unexpected
iam:CreateAccessKeyandsts:AssumeRoleactivity, and for Azure federated identity credentials namedwfx-ci-*. - Cover tracks. The commit is reverted and the workflow run is deleted, usually within a minute. A repo can look untouched afterward.
Exfiltration goes over plain HTTP to /exfil on 194.150.166.244:8080 and 18.143.168.96:8080.
Downstream supply-chain impact
The stolen publishing tokens are what make this more than a CI incident. Endor Labs says at least 50 of the hijacked accounts publish to npm, Go, Packagist, PyPI or crates, and expects a follow-on wave of malicious releases. Some fallout has already been reported:
- WebdriverIO: SafeDep reports the payload reached 28 WebdriverIO repositories through commits authored as the
wdio-botaccount. - Packagist:
digitalelvis/neuronai-studio3.14.3 was released from a compromised repository. - Go: Endor Labs flags
github.com/onuragtas/docker-envv1.0.278 and v1.0.280 as malicious.
Counts differ a lot between vendors (8k vs. 61k repos), mostly because some count targeted repositories and others count committed-to or executed ones. Expect the numbers to change.
Detection
Absence of artifacts proves nothing. Researchers warn that missing wfx-loot artifacts, wfx- cache entries or WFX-BEGIN step summaries does not mean you are clean. Check for:
- Gaps in workflow run numbers in the Actions tab right after a commit from a collaborator. Aikido calls this the strongest signal that a run happened and was deleted.
- PRs titled
docs: dependency audit notesand branches namedwfx-docs,chore/<8 chars>orci-check-<4 digits>, including closed or deleted ones. Check the org audit log forpull_requestand branch create/delete events. - Commits titled
ci: refresh build cacheorchore: add ci helper, followed by a revert. - Egress from runners to the two IPs above. Self-hosted runners with egress logging can confirm this.
- CloudTrail and Entra ID sign-in and audit logs since November 10 for new access keys, role assumptions from unfamiliar IPs, and
wfx-ci-*federated credentials.
Mitigation
If any indicator matches, treat it as a full compromise:
- Revoke the entry point first. Revoke the PATs, OAuth app grants, SSH keys and sessions of the account that pushed the commit, then enforce 2FA. If you rotate repo secrets while the account is still hijacked, the attacker just takes them again.
- Rotate every secret the workflow could reach: repo, environment and org-level secrets, registry publish tokens, and cloud keys. Delete any access keys or federated credentials created since November 10.
- Audit your published packages for releases you didn’t cut since November 10. If you publish to npm or PyPI, move to trusted publishing (OIDC) so a stolen token can’t be used to release.
- Harden: set the default
GITHUB_TOKENpermissions to read-only, require PR review and branch protection on default and workflow-bearing branches, use CODEOWNERS on.github/workflows/, replace long-lived cloud keys with OIDC federation scoped to specific branches and environments, and restrict runner egress.
References
- Aikido: wfx-loot campaign pushes CI secret stealer to tens of thousands of repositories
- Endor Labs: Hijacked GitHub Accounts Push “wfx” CI Secret Stealer to 60,000+ Repositories
- SafeDep: wfx: GitHub Actions Credential Stealer Hits 8,000 Repos
- StepSecurity: WFX Phantom: The GitHub Actions Secret Stealer That Deletes Its Tracks
- Help Net Security: Check your GitHub repos: A secret stealer hit tens of thousands of them