Title: Compromised GitHub Accounts Push wfx Secret Stealer into 8,000+ Repositories
Summary:
A campaign tracked as wfx-loot, first reported by Aikido Security and independently analyzed by SafeDep, has been using stolen GitHub tokens since roughly 12:45 UTC on November 10 to plant a credential stealer in other people’s repositories. Aikido counts 4,837 compromised accounts opening probe pull requests titled “docs: dependency audit notes” from wfx-docs branches in 61,764 repositories — the probe alone means the account is compromised, even if no payload followed — with the stealer actually running in at least 1,806 repositories. SafeDep’s default-branch search counted 8,093 repositories receiving malicious commits between November 10 at 12:46 UTC and November 12 at 04:36 UTC (an undercount, as it covers only public default branches, and the campaign was still live). Delivery comes in three flavors: ~1,500 lines injected into an existing workflow (“ci: refresh build cache”, 7,309 repos), an npm postinstall hook that runs the script on any npm install, including a developer’s machine (“chore: add ci helper”, 771 repos), or a new workflow file on a throwaway branch. The payload sweeps Actions secrets and variables, the workflow GITHUB_TOKEN and OIDC tokens, process memory and credential files for AWS, Azure, GCP, Kubernetes, npm, PyPI, SSH and AI providers, then exchanges GitHub OIDC tokens for cloud sessions and builds persistence: rewriting an AWS role’s trust policy to open it to any account and adding wfx-ci- federated identity credentials to Entra ID applications, so workflows in the repository can sign in to Azure even after all tokens rotate. Data leaves by HTTP POST to 194.150.166[.]244:8080/exfil, 18.143.168[.]96:8080/exfil or 153.75.82[.]159:8080, or to a Telegram chat (about a fifth of a 200-commit sample used Telegram only). The attacker typically reverts the commit and deletes the run and its logs within minutes. Per SafeDep, the better tell that the payload actually ran is a run number gone missing on the attacker’s commit — clean wfx-loot artifacts don’t clear a repository. The payload also reached packages: treat Packagist digitalelvis/neuronai-studio v3.14.3 as malicious (block it, pin v3.14.2 or earlier; only npm install inside its vendor directory runs the payload), and the Go modules github.com/onuragtas/docker-env (now redock) v1.0.278, v1.0.280 and v1.0.282 plus github.com/vkuznet/gocurl pseudo-version v0.0.0-20261111095532-8d5aad0cb0da carry it in workflow files that Go builds never execute, but which should be removed before any tagged build fires. Accounts overlap with October’s GhostAction wave but Aikido assesses the two campaigns as distinct actors. Response, per SafeDep and Aikido: for any repository that received a probe, revoke every credential the commit author had — tokens, OAuth app grants, SSH keys, live sessions — and switch on 2FA; rotate every secret the repository’s workflows can read; treat any machine that ran npm install on an affected commit as compromised; and hunt for backdoors — Entra ID federated credentials named wfx-ci-*, AWS CloudTrail AssumeRoleWithWebIdentity/AssumeRole sessions named wfx-* followed by CreateAccessKey or UpdateAssumeRolePolicy, GCP GenerateAccessToken/SignJwt calls from the GitHub workload identity pool, and Vault JWT logins from the GitHub OIDC issuer.
References: