wfx-loot Campaign Hits 61,000+ GitHub Repos, Aikido Says

Aikido Security says a campaign it calls wfx-loot used stolen GitHub tokens to probe over 61,000 repositories, exfiltrating CI/CD secrets from at least 1,806 of them since November 10.

GitHub's Octocat logo in white against a dark, pixelated background
Featured image from Aikido Security's report on the wfx-loot campaign. Image: Aikido Security.

A threat actor used stolen GitHub tokens to probe more than 61,000 repositories starting November 10, 2026, pushing a credential-stealing CI/CD payload that Aikido Security has code-named wfx-loot. In a post published November 12, Aikido says 4,837 compromised accounts opened probe pull requests across 61,764 repositories, and that it has found indications the payload actually ran and exfiltrated credentials in at least 1,806 of them. This is a separate, newly surfacing campaign from the Polinrider npm attack reported a day earlier, and from October's GhostAction wave, though Aikido found overlap between the two victim pools.

Key facts, as reported by Aikido Security
  • 4,837 compromised GitHub accounts opened "probe" pull requests in 61,764 repositories, starting at approximately 12:45 UTC on November 10.
  • Aikido has found indications the payload ran and secrets were exfiltrated in at least 1,806 repositories, though it says deleted run logs mean the true number is likely higher.
  • 10,431 of the probe pull requests landed in repositories the compromised account did not own, reached through collaborator or organization access; 92% remained open as of publication.
  • At least 50 compromised accounts publish packages to npm, Go, Packagist, PyPI or crates; two malicious releases have been confirmed so far, on Packagist and in a Go module.
  • Aikido assesses this as a distinct campaign from October's GhostAction wave, run by a likely different actor, despite victim overlap.

What is the wfx-loot campaign?

wfx-loot is the name Aikido Security gave this campaign, based on strings the malware itself uses: the threat actor's own name for the tool and the term it uses internally for stolen secrets. Aikido says a threat actor began using compromised GitHub credentials on November 10 to open throwaway pull requests against any repository those tokens could write to, confirm write access, then quietly push one of three malicious-workflow variants before reverting the change and deleting the run log, typically within a minute.

The goal, per Aikido, is CI/CD secrets and cloud credentials, not broad software-supply-chain proliferation. The researchers note the payload has spread into at least one Packagist package and one Go module through automated publishing pipelines, but write that "the threat actor appears to be targeting CI secrets rather than attempting to proliferate through the supply chain."

How big is the attack: the numbers Aikido has actually published

Because this story has circulated with different figures attached to it, it is worth being precise about what Aikido's own post says, as of its November 12 publication, and where its own count is still provisional. The table below uses only numbers stated in Aikido's post.

MetricAikido's reported figure
Compromised accounts that opened probe pull requests4,837
Repositories that received a probe pull request61,764 (Aikido's running count); a live GitHub search returned 61,839 matching pull requests
Probe PRs opened into repos the account doesn't own (collaborator/org access)10,431, of which 92% were still open
Repositories with confirmed indications the payload ran and secrets were exfiltrated"At least 1,806" — Aikido's summary section separately cites "at least 1,835"; the post does not reconcile the two figures, and says deleted logs mean the real number is likely higher
Compromised accounts that publish packages (npm, Go, Packagist, PyPI, crates)At least 50
Confirmed malicious package releases2: Packagist package digitalelvis/neuronai-studio 3.14.3, and Go module github.com/onuragtas/docker-env v1.0.278 and v1.0.280
Attack window (first wave)November 10, 12:45 UTC – November 11, 15:00 UTC

Two things are worth flagging for anyone citing this story onward. First, Aikido's own post contains two different figures for exfiltration-confirmed repositories — 1,835 in its summary bullets and 1,806 in its detailed walkthrough — without explaining the gap; treat both as "roughly 1,800-plus" rather than an exact count. Second, Aikido does not state how many distinct organizations are affected, only accounts and repositories, so headlines converting this into an organization count are extrapolating beyond what the primary source says.

How the attack works: probe, payload, cleanup

For every repository a stolen token could write to, Aikido describes a three-step pattern:

  • Probe. The attacker opens a pull request titled "docs: dependency audit notes" from a branch named wfx-docs. This does nothing except confirm the stolen token still has write access — Aikido says any account where this probe succeeded should be treated as compromised, whether or not the next stage ran.
  • Payload. The attacker pushes one of three variants: a workflow injection (commit message "ci: refresh build cache", adding roughly 1,500 lines to an existing workflow file); an install hook (commit "chore: add ci helper", which drops a .ci-xxxxxx.sh script and wires it into a postinstall hook in package.json so it runs on any npm install); or a throwaway branch (commit "chore: add dependency audit workflow", adding .github/workflows/build-audit-xxxxxx.yml on a branch named chore/ plus eight random characters).
  • Cleanup. The attacker reverts the change within about a minute and deletes the workflow run along with its logs. Aikido says a missing run number in a repository's workflow history is often the only remaining trace once this happens.

What the stealer collects

Aikido describes the payload as a single, roughly 1,500-line shell script — the same script across all three delivery variants — that is "heavily commented, not obfuscated" and self-identifies as "wfx" in its own logs and variable names. The script runs in four stages, each independently toggled by configuration flags: collect, escalate, persist, and exfiltrate.

In the collection stage, per Aikido's writeup, the script pulls GitHub Actions secrets and variables, the job's GITHUB_TOKEN, and OIDC/Actions runtime tokens; the full runtime environment plus any variable matching keywords like token, secret, aws, azure, gcp, openai, anthropic, or stripe; credential files for AWS, Azure, GCP, Docker, Kubernetes, npm, PyPI, Git, SSH, GPG, Vault and Terraform; API keys for AI tools including OpenAI, Anthropic/Claude, Gemini, Hugging Face, Cursor, Copilot, Codex, Continue, Codeium, Aider and Ollama; shell histories; and any .env, .pem, .p12, .jks, .kdbx or kubeconfig file under the home directory. It also scans the memory of running processes, prioritizing the Actions runner's own worker process, to pull JWTs, GitHub personal access tokens, AWS keys, and AI-provider tokens directly out of memory. On self-hosted runners specifically, Aikido says it additionally grabs cloud instance-metadata credentials, Docker container state, the runner's own RSA key material, and systemd unit files.

How attackers escalate and persist after the initial theft

Aikido's analysis describes an escalation stage that turns short-lived CI credentials into durable cloud access: minting GitHub OIDC tokens and exchanging them for AWS, GCP and Azure sessions; chaining into other IAM roles found in the repository and calling iam:CreateAccessKey to mint long-lived AWS credentials; signing JWTs with GCP service-account keys to impersonate service accounts; and replaying cached Azure CLI refresh tokens against Microsoft's own first-party client IDs to obtain Graph, ARM and Key Vault tokens.

The persistence techniques are the most notable part of the report. Aikido says the payload posts forged, passing status checks against the commit it is running from — before most of the collection has even happened — which clears branch-protection merge gates that match on check name rather than on which app posted them. Separately, where it gains AWS role access, it rewrites the role's trust policy to "Principal": {"AWS": "*"}, opening that role to any AWS account. And with a Microsoft Graph token, it adds new federated identity credentials — named wfx-ci-… — to Azure AD applications, which Aikido says lets any workflow in the compromised repository authenticate to Azure indefinitely, with no stored secret, even after every token has been rotated.

How stolen secrets leave the network

The script packages everything it collects into a gzipped tarball and, per Aikido, supports several exfiltration channels — including three that ride GitHub's own infrastructure specifically to sidestep network egress controls: storing the tarball as an Actions cache entry, base64-encoding it into a workflow step summary between <!--WFX-BEGIN--> markers for payloads under 700KB, or uploading it as a workflow artifact named wfx-loot-<run id>. In the wave Aikido examined, none of those three were switched on; the only active channel was a direct HTTP POST, with retry back-off, to one of two IP addresses the firm has published as indicators of compromise. Aikido cautions that the absence of cache entries, artifacts or step-summary markers in a given repository does not clear it, since the run itself — and its logs — are typically deleted once the script finishes.

Which packages and ecosystems are affected

Aikido says at least 50 of the compromised accounts are maintainers who publish to npm, Go, Packagist, PyPI or crates.io, and that it has so far confirmed the campaign reaching published packages through automated publishing triggers in two cases: version 3.14.3 of the Packagist package digitalelvis/neuronai-studio, and versions v1.0.278 and v1.0.280 of the Go module github.com/onuragtas/docker-env. For the Go module, Aikido notes the payload sits only inside a GitHub Actions workflow file bundled with those tags — the Go source and compiled release binaries are unaffected, and a standard go build never executes repository workflow files — though it still recommends removing the tagged versions. Aikido's post does not name any affected npm or PyPI package, only the ecosystems its compromised maintainers publish to.

Is this related to October's GhostAction campaign?

Partly, but Aikido treats wfx-loot and October's GhostAction wave as two separate campaigns, likely run by different actors, despite real overlap in who got hit. Aikido says accounts previously compromised in GhostAction were significantly more likely than baseline to also be hit by wfx-loot, and that in more than 100 repositories, the wfx-loot payload was injected directly into existing GhostAction workflow files. It points to differing infrastructure and tradecraft as its basis for calling them distinct operations, while noting stolen credentials frequently change hands between threat actors. One tell Aikido flags: newer wfx-loot variants carry Indonesian-language code comments tied to a hastily added Telegram-exfiltration feature — language it says has never appeared in GhostAction samples. GhostAction's own known indicators, which Aikido lists separately, include workflow files named security-audit.yml, audit.yml or ci-check.yml, and a developer-machine stealer disguised as a font file (public/fonts/fa-solid-400.woff2) that runs via a hidden VS Code task — a reminder that editor automation features are now a live part of some attackers' toolkits, not just CI pipelines.

How to tell if your repository was hit

Based on Aikido's indicators, check for any of the following appearing in a repository you can write to, on or after November 10:

  • A branch named wfx-docs, or any pull request titled "docs: dependency audit notes."
  • Commits titled "ci: refresh build cache," "chore: add ci helper," or "chore: add dependency audit workflow."
  • Short-lived branches named chore/ followed by eight random characters, or ci-check- followed by four digits.
  • Outbound connections in workflow logs (where logs still exist) to 194.150.166[.]244:8080 or 18.143.168[.]96:8080.
  • A gap in your Actions run-number sequence — Aikido says a missing run number on an otherwise-unexplained commit is often the most reliable remaining sign, since the attacker typically deletes the run itself.

If the probe pull request appears at all, Aikido's guidance is to treat the account as compromised even if there's no evidence the payload stage executed. If the payload did run, its guidance is blunter still: assume every secret and cloud role available to that workflow is compromised.

How to protect yourself and your organization

Aikido's own recommendations, combined with GitHub's general CI/CD hardening guidance, point to the same set of actions:

  • Rotate first, investigate second. For any repository showing the indicators above, rotate every secret and cloud credential available to its workflows — don't wait to fully reconstruct what was taken.
  • Audit cloud trust relationships, not just secrets. Because the payload rewrites AWS role trust policies and adds Azure federated identity credentials, rotating a password or API key alone won't undo the backdoor. Check AWS roles for a trust policy of "Principal": {"AWS": "*"}, and search Azure AD applications for federated credentials named wfx-ci-….
  • Apply least privilege to GITHUB_TOKEN and workflow permissions, and pin third-party Actions to a full commit SHA rather than a mutable tag, per GitHub's own security hardening guide for Actions.
  • Treat a compromised repository's whole account as suspect, following the account-recovery steps in GitHub's own writeup on hardening repositories against credential theft: reviewing personal access tokens, resetting two-factor recovery codes, and auditing recently added collaborators.
  • Don't rely on branch protection alone. Because the payload forges passing status checks that match protected branches' required-check names, status checks from unfamiliar or newly added apps are worth auditing even when they appear to pass.
  • Review open pull requests, including ones you've ignored. Aikido notes 92% of the probe PRs it found are still open, which it reads as a sign most repository owners haven't noticed them yet.

What's next

Aikido says it is still gathering data and that its own published figures — particularly repository counts tied to deleted workflow runs — likely understate the campaign's true reach. The firm has not said whether GitHub itself has taken action against the compromised accounts, revoked tokens at the platform level, or opened its own advisory; Pandromeda has not found a GitHub-published security advisory specific to this campaign as of publication, and will update if one appears. In the meantime, Aikido is pushing updates to its own scanning products — it says compromised-package detections surface as 100/100-critical issues in its platform, with nightly automatic rescans — and is promoting its open-source Safe Chain tool, which intercepts npm, npx, yarn, pnpm and pnpx commands to check packages before install. Given the campaign's apparent overlap with October's GhostAction activity, and the fact most probe pull requests are still sitting open and unreviewed, this is likely to keep generating follow-up reporting over the coming days, in much the way prior GitHub Actions-targeted supply chain attacks have played out in waves rather than single disclosures.

Frequently asked questions

What is the wfx-loot campaign?

wfx-loot is Aikido Security's name for a campaign it reported on November 12, 2026, in which a threat actor used stolen GitHub tokens to open probe pull requests in tens of thousands of repositories, then pushed a credential-stealing CI/CD payload before deleting the evidence.

How many GitHub accounts and repositories were affected?

Aikido says 4,837 compromised accounts opened probe pull requests across 61,764 repositories, and that it has found indications the payload ran and exfiltrated secrets in at least 1,806 of them, though it cautions deleted logs mean the true number is likely higher.

Is wfx-loot the same as October's GhostAction campaign?

No. Aikido found overlap in which accounts were hit by both campaigns, and found wfx-loot injected into existing GhostAction workflow files in over 100 repositories, but assesses the two as distinct campaigns likely run by different threat actors, citing differing infrastructure and tradecraft.

What should I do if I think my repository was affected?

Check for the indicators Aikido published, such as a wfx-docs branch, a 'docs: dependency audit notes' pull request, or a missing Actions run number. If any appear, rotate every secret and cloud credential available to that workflow, and audit AWS role trust policies and Azure AD federated credentials for unauthorized entries.

Does wfx-loot affect npm or PyPI packages directly?

Aikido has confirmed the payload reaching two published packages so far: a Packagist package (digitalelvis/neuronai-studio 3.14.3) and a Go module (github.com/onuragtas/docker-env, v1.0.278 and v1.0.280). It says at least 50 compromised accounts publish to npm, Go, Packagist, PyPI or crates, but has not named a specific npm or PyPI package as compromised.

Who discovered and reported the wfx-loot campaign?

Aikido Security, a software supply-chain security vendor, published its findings on November 12, 2026, and says it is still gathering data on the campaign's full scope.

Sources

More on Supply Chain Attack →Supply Chain AttackGitHub SecurityCI/CD SecretsGitHub Actionswfx-loot
Felix Moreau
Written byFelix Moreau

Felix Moreau writes Pandromeda's software coverage and how-to guides. He covers Windows, macOS and Linux updates, the apps people rely on, emulators and developer tools, and turns official documentation into clear, numbered steps that work on the current version.

More from Software & Guides

See all