Skip to main content
Online Security

GitHub Account Hijack: wfx-loot Campaign Steals Secrets

Published 12 min read
A code repository tree with keys siphoned from one branch, illustrating the GitHub account hijack wfx-loot campaign

In short

According to researcher reports published on 12 November 2026, the wfx-loot campaign used about 4,800 compromised GitHub accounts to probe more than 61,000 repositories and plant a CI secret stealer, which Aikido says ran in at least 1,806 of them [1]. It abuses stolen tokens, not a GitHub bug [2], and reverts its changes within about a minute [1].

Key takeaways

  1. Aikido Security says the campaign began around 12:45 UTC on 10 November 2026 [1].
  2. 4,837 compromised accounts opened probe pull requests titled 'docs: dependency audit notes' in 61,764 repositories [1].
  3. The stealer ran in at least 1,806 repositories, a figure Aikido says may understate impact [1].
  4. It grabs GitHub Actions secrets, cloud credentials and AI service keys, then reverts its commit and deletes the workflow run [1][2].
  5. A missing workflow run number right after a suspicious commit is the most reliable sign the stealer ran [2].
  6. If it ran, rotate every secret the workflow could reach and remove cloud backdoors, because rotation alone is not enough [2].
On this page 12 sections
  1. What is the wfx-loot GitHub campaign?
  2. How big is the wfx-loot attack?
  3. How does the wfx-loot stealer work?
  4. Why is rotating secrets not enough?
  5. How do I check if my GitHub repositories were hit?
  6. What should I do if the stealer ran?
  7. Which packages were affected?
  8. Who is behind wfx-loot and how did they get the tokens?
  9. Common mistakes
  10. Frequently asked questions
  11. Glossary
  12. Sources

What is the wfx-loot GitHub campaign?

wfx-loot is a campaign in which an attacker uses stolen GitHub credentials to push a malicious workflow into repositories those accounts can write to, stealing GitHub Actions secrets and cloud credentials [1]. Aikido Security, which first reported it, named it after the attacker's own name for the malware ("wfx") and the word used for stolen secrets ("loot") [1]. SafeDep also credits Aikido with the first report [5].

StepSecurity calls the same stealer "wfx" and stresses a key point: the attacker does not exploit a bug in GitHub Actions [2]. Instead it uses valid tokens for real developer and bot accounts, opening pull requests and pushing commits the way a developer would [2][4].

Aikido believes the main goal is CI secrets rather than spreading through software packages, although the payload did reach at least one Packagist and one Go package through automated publishing triggers [1]. BleepingComputer, relying on Aikido's analysis, reports that some of the compromised accounts belonged to large organisations [3].

How big is the wfx-loot attack?

Aikido counts 4,837 compromised accounts that opened probe pull requests in 61,764 repositories, with the stealer running in at least 1,806 repositories [1]. Figures differ slightly between researchers because each searched GitHub at a different time while the campaign was still active.

  • Aikido: 4,837 accounts, 61,764 repositories; 10,431 pull requests went into repositories the account does not own; 92% still open; at least 50 compromised users publish packages to npm, Go, Packagist, PyPI or crates [1].
  • Aikido (summary figure): at least 1,835 repositories ran the payload and had credentials taken; BleepingComputer uses this number [1][3].
  • StepSecurity: more than 63,000 probe pull requests as of 07:40 UTC on 12 November, about 90% still open [2].
  • SafeDep: 8,093 repositories received malicious commits between 10 and 12 November, a figure that, as SecurityWeek notes, does not necessarily mean the stealer executed [5][4].

Aikido warns its execution count may understate impact, because the run logs were deleted in affected repositories [1].

How does the wfx-loot stealer work?

For each repository a stolen token can write to, the attacker probes, pushes the payload, then cleans up within about a minute [1].

  1. Probe: a pull request titled "docs: dependency audit notes" from a branch named wfx-docs adds a tiny notes file. "The pull request does nothing by itself," StepSecurity says; it only shows that the token has write access [2][4].
  2. Payload: a shell script of about 1,500 lines arrives in one of three ways: injected into an existing workflow ("ci: refresh build cache"), as a script plus an npm postinstall hook ("chore: add ci helper"), or as a new workflow on a throwaway chore/ branch ("chore: add dependency audit workflow") [1].
  3. Clean-up: the attacker reverts the change and deletes the workflow run and its logs [1]. A missing run number is often the only trace [1].

The script collects GitHub Actions secrets and tokens, the full runner environment, credential files for AWS, Azure, Google Cloud, Docker, Kubernetes, npm, PyPI, SSH and more, shell histories, and keys for AI providers and developer tools [1][3]. It even reads the memory of running processes on the runner [1][4]. Aikido found that the copies it analysed sent the stolen data only by HTTP POST to attacker-controlled servers [1]. StepSecurity later saw a change: from about 05:30 UTC on 12 November, new copies sent data only through Telegram, so blocking the published server addresses alone no longer stops them [2].

Glowing cubes on a conveyor with one cracked cube spilling gold coins into a pipe, showing stolen CI secrets
The stealer collects every secret the workflow can reach.

Why is rotating secrets not enough?

Because the stealer tries to plant backdoors that survive credential rotation [1][2]. Aikido describes three persistence tricks [1]:

  • Forged status checks: Aikido says it posts fake "success" checks using the names of a repository's required checks, which can clear branch-protection merge gates [1]. StepSecurity found this feature switched off in all 101 samples it examined [2].
  • AWS trust policy rewrite: it can set a role's trust policy to allow any AWS account [1].
  • Azure federated identity injection: it can add federated credentials named wfx-ci-… to Azure AD applications, letting workflows in the compromised repository authenticate without a stored secret [1].

It can also mint GitHub OIDC tokens and exchange them for AWS, Google Cloud and Azure sessions, chain into other IAM roles and create long-lived AWS access keys [1][3]. That is why StepSecurity says to "remove the persistence, because rotation alone does not" [2].

A cloud-shaped steel vault with a gold lock and a small red-lit hatch left ajar, illustrating hidden cloud backdoors
Rotating keys does not close backdoors already planted in AWS or Azure.

How do I check if my GitHub repositories were hit?

Search for the probe pull request and the attacker's commit messages since 10 November, then look for gaps in workflow run numbers [2][1].

  1. Search pull requests for "docs: dependency audit notes" and branches named wfx-docs or chore/ followed by eight characters [1][2].
  2. Search commits since 10 November for "ci: refresh build cache", "ci: restore", "ci: cleanup", "chore: add ci helper" and "chore: add dependency audit workflow" [2].
  3. For each hit, open the Actions tab and look for a missing run number right after the commit; StepSecurity calls this the most reliable sign the stealer ran [2].
  4. Note which account pushed the commits: that account's tokens are stolen [2]. If a probe pull request exists, the account is compromised even if no payload ran [1].

Do not rely on missing artefacts. Aikido says the absence of wfx-loot artifacts, wfx- cache entries or special step summaries does not mean data was not taken, because those channels were switched off in this campaign [1]. Aikido also suggests the payload may be deployed in private repositories as well as public ones [1].

A row of tiles with one missing, illustrating the deleted workflow run that reveals the wfx-loot GitHub attack
A missing run number is the most reliable sign the stealer ran.

What should I do if the stealer ran?

Assume every secret and cloud role available to the affected workflow is compromised, rotate them, and then hunt for persistence [1][2].

  • Rotate: every repository, environment and organisation secret the job could reach, not just the ones the workflow names; npm, PyPI and other publishing tokens; and cloud keys stored as secrets [2].
  • Check packages: look for package versions published after the malicious commit [2].
  • AWS: look for trust policies allowing any AWS principal, IAM access keys created since 10 November, and CloudTrail sessions starting wfx- [2].
  • Azure: delete federated identity credentials named wfx-ci-* on app registrations [2].
  • Google Cloud, Vault, Kubernetes: review token generation and logins made with GitHub Actions sign-in tokens [2].
  • GitHub: delete leftover branches, close probe pull requests, check nothing was merged on a forged check, and revoke the account's tokens, OAuth grants and SSH keys [2].
  • Tokens, per GitHub's documentation: review your personal access tokens under Settings, Developer settings and delete any you do not recognise or need; GitHub recommends fine-grained tokens, only the minimal permissions necessary and an expiration date, because a classic token can access every repository you can access [6].

The npm hook also runs on developer machines: anyone who ran npm install during the short window ran the stealer locally and should rotate their own credentials too [2]. SecurityWeek sums up the advice from several security firms: revoke compromised tokens, rotate exposed secrets and check for unauthorised cloud changes [4]. For bot accounts, StepSecurity also suggests reviewing whether they need permission to bypass branch protection at all [2]. Strong sign-in protection makes stolen-account campaigns harder; see Two-Factor Authentication Explained: Which 2FA Method Is Safest?.

Which packages were affected?

Aikido lists a Packagist package and a Go module that picked up the payload through automated publishing [1].

  • Packagist: digitalelvis/neuronai-studio version 3.14.3; Aikido says to treat any machine that installed or opened it as compromised [1].
  • Go: github.com/onuragtas/docker-env v1.0.278 and v1.0.280; the payload is only in a GitHub Actions workflow file, the Go source and binaries are unchanged, and Go builds never run workflow files, but Aikido still recommends removing these versions [1].

Counts differ: SafeDep says three packages on Packagist and the Go module proxy ship the payload, and SecurityWeek mentions versions of two Go modules [5][4]. SafeDep adds that the payload did not run for typical consumers who install these packages with composer require or go get [5]. Check each researcher's current list before relying on any one of them.

Who is behind wfx-loot and how did they get the tokens?

None of the reports named here identifies the attacker, and StepSecurity says it has not established how the tokens were obtained [2][4].

StepSecurity found 173 probe pull requests, from 19 accounts, made through tokens issued to the Fly.io GitHub App; it said it could not determine how they were obtained and had no evidence that Fly.io's infrastructure was breached [2][4].

Aikido found overlap with accounts hit by the October GhostAction wave and saw wfx-loot injected into GhostAction workflow files in more than 100 repositories, but assessed the two as distinct campaigns likely run by different actors, since stolen credentials often end up with several groups [1]. It also noticed Indonesian-language comments in some newer malware versions [1]. Storing tokens carefully matters here; Password Managers Explained: How They Work and Whether They Are Safe covers the basics.

wfx-loot campaign figures by researcher (as reported on 12 November 2026)
MeasureFigureSource
Compromised accounts4,837Aikido
Repositories probed61,764Aikido
Repositories where stealer ranat least 1,806-1,835Aikido
Repositories with malicious commits8,093SafeDep
Probe pull requestsmore than 63,000 (12 Nov, 07:40 UTC)StepSecurity

Common mistakes

  • Assuming a clean branch means no theft.

    Fix: The attacker reverts commits; check for missing run numbers [1][2].

  • Only rotating the secrets the workflow names.

    Fix: The memory scan collects the rest; rotate everything reachable [2].

  • Stopping after rotation.

    Fix: Remove AWS and Azure persistence too [2].

  • Blaming a GitHub Actions bug.

    Fix: The attacker uses valid stolen tokens [2].

  • Ignoring an open probe pull request.

    Fix: It means the account is compromised [1].

Frequently asked questions

What is the wfx-loot GitHub campaign?

A campaign using stolen GitHub tokens to plant a CI secret stealer in repositories [1].

How big is the wfx-loot attack?

4,837 accounts probed 61,764 repositories; the stealer ran in at least 1,806 [1].

How does the wfx-loot stealer work?

Probe PR, then a ~1,500-line script via workflow or npm hook, then revert and delete logs [1].

Why is rotating secrets not enough?

Aikido describes AWS and Azure backdoors that survive rotation; StepSecurity says to remove the persistence because rotation alone does not [1][2].

How do I check if my GitHub repositories were hit?

Search for the probe PR and commit messages, then look for missing run numbers [2].

What should I do if the stealer ran?

Rotate all reachable secrets, check packages and remove cloud persistence [2].

Which packages were affected?

Aikido lists Packagist digitalelvis/neuronai-studio 3.14.3 and Go docker-env v1.0.278 and v1.0.280; SafeDep lists more [1][5].

Who is behind wfx-loot and how did they get the tokens?

Not identified in the reports; StepSecurity traced some probes to Fly.io GitHub App tokens and has not established how they were obtained [2].

Glossary

GitHub Actions
GitHub's built-in CI/CD system that runs workflows on code changes [1].
CI secret
A password, token or key stored for use by automated build workflows [1].
OIDC token
A short-lived identity token a workflow can exchange for cloud access [1].
Probe pull request
A harmless-looking PR used to test write access [2].
Persistence
Access an attacker keeps after the original credentials are changed [2].

Sources

  1. wfx-loot campaign pushes CI secret stealer to tens of thousands of repositories Aikido Security · 2026-11-12
  2. WFX Phantom: The GitHub Actions Secret Stealer That Deletes Its Tracks StepSecurity · 2026-11-12
  3. Hackers compromise 4,800 GitHub accounts to steal cloud credentials BleepingComputer · 2026-11-12
  4. Attacker Targets 60,000 GitHub Repositories in Credential Theft Campaign SecurityWeek · 2026-11-12
  5. wfx: GitHub Actions Credential Stealer Hits 8,000 Repos SafeDep · 2026-11-12
  6. Managing your personal access tokens GitHub Docs
Share this guide Telegram WhatsApp X
0 likes

Comments

Top comments

About the Pouyam Team Editorial policy

On Pouyam

Explore Pouyam

Guides are one corner of Pouyam. Here is where to go next.

Quick navigation