FR
live

A campaign steals CI secrets from 1,800 repositories through 4,837 compromised GitHub accounts

Between November 10 and 11, 2026 an actor used credentials for 4,837 GitHub accounts to plant a secret stealer in the workflows of tens of thousands of repositories, according to Aikido Security. If you received a "docs: dependency audit notes" pull request after November 10, treat every secret in your pipeline as compromised.

A row of identical metal lockers in a data center corridor, a single door slightly ajar leaking a sliver of amber light.

November 10, 2026, 12:45 UTC. An actor starts using stolen GitHub credentials to push code into repositories. November 11, 2026, 15:00 UTC. The burst of probe pull requests stops, after reaching 61,764 repositories. November 12, 2026. Aikido Security publishes its analysis and names the campaign wfx-loot. Why it matters: the attacker was not after your code — it was after the secrets your CI workflows can read — and it exfiltrated those of at least 1,835 repositories.

What wfx-loot actually does

wfx-loot is the name Aikido Security’s researchers gave the campaign, from the term the actor itself uses for its tooling and the loot it collects. The scenario is platform-scale credential stuffing: the actor holds credentials — likely from earlier breaches or from stealers installed on developer machines — for 4,837 GitHub accounts whose authentication is not protected by a second factor.

For every repository those accounts can write to, the sequence is mechanical. First a probe: a pull request titled “docs: dependency audit notes” opened from a wfx-docs branch. Then, if the account has the rights, commits named “ci: refresh build cache”, “chore: add ci helper” or “chore: add dependency audit workflow” drop the real payload — a GitHub Actions workflow built to exfiltrate the CI secrets and cloud credentials the runner can reach. The branches use disposable names of the form chore/ followed by eight random characters.

A GitHub search returns 61,839 “docs: dependency audit notes” pull requests opened between November 10 at 12:45 UTC and November 11 at 15:00 UTC. 10,431 of them reached repositories the account does not own, through collaborator or organization access. And 92% are still open — which means most owners never noticed the probe.

The scale is the point. 4,837 accounts is not a targeted breach; it is a spray-and-pray operation where the attacker casts a wide net and lets each stolen account’s write permissions decide what gets infected. Most probes went nowhere — only about 1,835 repositories actually ran the payload — but at this volume even a low success rate yields thousands of valid production secrets, harvested once and then usable for months.

The pipeline becomes the attack surface

What changes everything is that the target is not the repository itself. It is the pipeline. A GitHub Actions workflow runs with the repository’s permissions and can read the secrets and cloud roles configured for it. By injecting a malicious workflow into a repository where a compromised account can write, the attacker runs its code inside the repository’s trust context — a context that opens up, depending on the setup, production API keys, registry credentials, or AWS, GCP or Azure roles the runner can assume.

Aikido estimates at least 1,835 repositories actually executed the payload, with credentials exfiltrated. The run logs were deleted in impacted repositories — a sign the attacker collected the loot and erased its tracks. The team notes the number is likely undercounted: you cannot tally what has been wiped.

The campaign also spilled into package ecosystems, through the compromised accounts’ automated publishing triggers. At least 50 compromised users publish packages on npm, Go, Packagist, PyPI or crates. Two malicious packages are identified so far: digitalelvis/neuronai-studio version 3.14.3 on Packagist, and the Go module github.com/onuragtas/docker-env versions 1.0.278 and 1.0.280 — the latter carries the payload only in a workflow file, which limits its impact to builds that would execute it.

It is a blunt reminder of a rule already documented on this blog: GitHub had to block pull_request_target precisely because workflows became a code-execution surface, and the Railway environment-variable leak already showed what a secret lingering in a pipeline costs.

In modern software, a CI secret is often worth more than source code. Source code is what a product is; a CI secret is what lets an attacker ship code as you — push releases, publish packages, or reach the cloud roles your deployments assume. That is why the stealer ignores the repositories themselves and goes straight for the workflow context.

Where 4,837 accounts come from

Aikido does not detail the origin of the credentials, but the profile is recognizable: accounts without two-factor authentication, whose passwords — or personal access tokens — leaked through infostealers, the malware that siphons sessions and passwords from developers’ browsers. That is the missing link of credential stuffing: without 2FA, a stolen credential equals write access. The campaign relies on no GitHub vulnerability, only on the reuse of already-compromised credentials — which makes it hard to attribute and easy to repeat. The operational lesson is blunt: 2FA is not optional on a platform where write access to repositories equals access to production.

How to tell whether you are affected

The warning sign is easy to search for. If any of these appeared in a repository you can write to on or after November 10, you are in scope:

  • a wfx-docs branch or a “docs: dependency audit notes” pull request;
  • commits named “ci: refresh build cache”, “chore: add ci helper” or “chore: add dependency audit workflow”;
  • a short-lived branch named chore/ followed by eight random characters.

Aikido’s rule is unambiguous: if the payload ran in your repository, assume every secret and cloud role available to your workflows is compromised. That means revoking and rotating all secrets — not just the ones you think were read — revoking sessions and keys for assumable cloud roles, and auditing workflow history for the injected file.

Beyond triage, two reflexes limit the damage: freeze the compromised accounts — revoke their tokens and sessions — and turn on 2FA everywhere, prioritizing accounts with write access to production repositories. Branch protection with mandatory approval, for its part, does not stop the probe — but it stops the payload from reaching the default branch without a human having seen it.

bash
# list workflows changed recently in a local clone
git log --since=2026-11-10 --name-only -- .github/workflows/ | grep -v '^$'

The durable fix is organizational, not technical: require review on every workflow change, enable branch protection with mandatory approval, and enforce 2FA on every account with access to production repositories. A workflow is executable code — it must be treated with the same rigor as a change to the application core.

Verdict

If a repository you can access received a “docs: dependency audit notes” pull request or a chore/ branch after November 10, 2026, treat all of its CI secrets and cloud roles as compromised and rotate them immediately, even if the workflow does not appear to have run — the probe alone confirms the account was compromised. The real risk is not what was already stolen, but what remains exploitable: still-valid production credentials in repositories where 92% of the probes are still open. If none of your repositories received these artifacts, the immediate risk is low, but the campaign is a case study for enforcing 2FA and mandatory workflow review right now — that is the only way to make this vector inert.

References

The cyber brief, every Tuesday

The flaws that matter and the patches to apply, in a ten-minute read.

No spam. One-click unsubscribe.
read next

On the same topic

Python’s CVEs triple in a year as PyPI removes 60% more malware

Seth Larson, the Python Software Foundation’s Security Developer-in-Residence, has put numbers on the ecosystem’s security load: CVEs in Python and pip tripled in a year and PyPI now removes 60% more malware. DevOps teams should lock down their dependency chains, because this signal volume is not going to fall back.

← Back to the feed

Type at least two characters.

↑ ↓ navigate ↵ open esc dismiss