Probe, Payload, Vanish: 4,837 Hijacked GitHub Accounts Fed a CI Secret Stealer Across 61,764 Repositories
Starting at approximately 12:45 UTC on 10 November 2026, a threat actor used stolen GitHub credentials belonging to 4,837 accounts to push a malicious workflow payload into repositories those accounts could write to. Aikido disclosed the campaign on 12 November 2026, reporting probe pull requests in 61,764 repositories and evidence that the payload actually executed in at least 1,806 of them — with the run logs deleted afterward. The payload is a single heavily commented, non-obfuscated shell script of about 1,500 lines, internally designated "wfx", that collects CI secrets and cloud credentials, escalates into cloud accounts, plants persistence that survives rotation, and exfiltrates everything as a gzipped tarball. The actor's goal, per Aikido, is CI secrets rather than supply-chain proliferation — but the payload still leaked into at least one published Packagist package and two Go module tags through automated publishing triggers.
How the wave worked: probe, payload, cleanup
For each repository a stolen token could write to, the actor followed a three-step rhythm. First the probe: a pull request titled "docs: dependency audit notes" opened from a wfx-docs branch, which simply confirmed write access. GitHub search shows 61,839 such probe PRs opened between 10 November 12:45 UTC and 11 November 15:00 UTC; 10,431 of them targeted repositories the compromised account didn't own, reached through collaborator or organisation access — and 92% were still open at disclosure time, suggesting most owners never noticed. Aikido is explicit that the probe alone compromises the account: if it ran, that user is compromised even if the workflow stage didn't.
Then the payload, delivered in one of three variants: workflow injection (a commit titled "ci: refresh build cache" adding ~1,500 lines to an existing workflow), an install hook ("chore: add ci helper" adding a .ci-xxxxxx.sh script plus a postinstall hook in package.json that runs it on any npm install), or a throwaway branch ("chore: add dependency audit workflow" adding .github/workflows/build-audit-xxxxxx.yml on a chore/xxxxxxxx branch). Then the cleanup: the actor reverted within a minute at most and deleted the workflow run along with its logs — a missing run number in the workflow's history is often the only trace left. Aikido warns the 1,806 figure may understate impact precisely because the evidence deletes itself.
What it steals — including your AI provider tokens
The script works in four stages — collect, escalate, persist, exfiltrate — with configuration flags toggling individual features. The collection stage is indiscriminate: GitHub Actions secrets and variables, the GITHUB_TOKEN, and OIDC plus Actions runtime tokens; the full runtime environment plus a filtered copy of variables matching token, secret, pass, cred, aws, azure, gcp, openai, anthropic, stripe and dozens of other keywords; credential files for AWS, Azure, GCP, Docker, Kubernetes, npm, PyPI, Git, SSH, GPG, Vault and Terraform; credentials for AI providers and developer tools including OpenAI, Anthropic/Claude, Gemini, Hugging Face, Cursor, Copilot, Codex, Continue, Codeium, Aider, Weights & Biases and Ollama; shell histories; every .env, .pem, .p12, .jks, .kdbx and kubeconfig file under $HOME; and the environment and memory of running processes — prioritizing Runner.Worker and Runner.Listener — extracting JWTs, GitHub PATs, AWS keys and AI provider tokens. On self-hosted runners it additionally grabs cloud instance-metadata credentials, Docker container state, the runner's RSA parameters and systemd units, plus a repository snapshot covering secret-pattern files, the last 100 commits and recent workflow artifacts.
Escalation converts stolen material into durable cloud access: minting GitHub OIDC tokens for AWS, GCP and Azure audiences and exchanging them for sessions; chaining into other IAM roles found in the repository and calling iam:CreateAccessKey to mint long-lived credentials; signing GCP JWTs with service-account keys via a dependency-free Python RSA implementation, then impersonating service accounts; exchanging Azure OIDC tokens or client secrets for management tokens and replaying cached Azure CLI (FOCI) refresh tokens against first-party Microsoft client IDs for Graph, ARM and Key Vault access; and replaying OIDC tokens against HashiCorp Vault and Kubernetes API servers. Persistence is designed to outlast rotation: forged success status checks posted early in the run under the repository's required-check context names (branch protection matches on context name, not on the posting app); an AWS trust-policy rewrite to "Principal": {"AWS": "*"}; and new federated identity credentials named wfx-ci-… added to Entra applications, letting any workflow in the compromised repository authenticate to Azure with no stored secret even after every token is rotated.
Exfiltration, packages, and the GhostAction overlap
In this campaign the payload was configured to exfiltrate only by direct HTTP POST to 194.150.166[.]244:8080/exfil or 18.143.168[.]96:8080/exfil. The script's stealthier channels — stashing the tarball in the Actions Cache API, base64-encoding it into step summaries between WFX-BEGIN markers, or uploading a wfx-loot-<run id> artifact — only activate under a private-repository flag that was turned off, as were the encrypted-commit fallback, the run-log channel and any secondary callback. Aikido stresses the negative inference explicitly: the absence of wfx-loot artifacts, wfx- cache entries or WFX-BEGIN summaries does not mean data wasn't taken, and the run itself is usually deleted. The dedicated private-repository configuration suggests the payload may also be running in private repositories invisible to outside measurement.
Two published packages carried the payload outward through automated publishing triggers: Packagist digitalelvis/neuronai-studio version 3.14.3 — treat any machine that installed it as compromised — and Go module github.com/onuragtas/docker-env tags v1.0.278 and v1.0.280, where the payload sits in a workflow file only (Go source and release binaries unchanged, Go builds never execute workflow files), though Aikido still recommends removal. The compromised accounts overlap heavily with October's GhostAction wave — the secret-scanning workflows phoning home to 193.32.204[.]199 and the fa-solid-400.woff2 developer-machine stealer with its hidden VS Code task and #ghc2 cron job. Accounts hit in October were about a thousand times more likely than other active accounts to be reused in November, and in over 100 repositories the November payload was injected into leftover October workflow files. Aikido nevertheless declines to attribute November to the same actor: infrastructure, tooling and tradecraft differ, and stolen credentials routinely end up in several actors' hands.
Why this one is worse than the average secret-stealer wave
Three properties compound. First, the probe-then-vanish tradecraft exploits the trust model of CI itself: a reverted commit is not an all-clear, because the run already executed with the repository's full secret scope — and the deletion of the run removes the evidence most teams would check. Second, the persistence primitives (forged checks, open trust policies, federated identity injection) convert a transient CI execution into standing access that survives the credential rotation most incident playbooks stop at. Third, the explicit targeting of AI provider and coding-assistant credentials — OpenAI, Claude, Gemini, Cursor, Copilot, Codex, Hugging Face — means one compromised CI environment can fund downstream agent-abuse campaigns, connecting this wave directly to the pattern of AI development tools as mass-harvesting footholds. Our GhostAction October-wave coverage and the history-sweep briefing document the precursor infrastructure; the fake-font developer-machine stealer is the reason October victims' credentials were available for November reuse. The cloud-escalation thread parallels our Qubole cross-account trust coverage, and the standing-secret exposure rhymes with the Claude Code local-settings secret exposure — linked, not restated.
What to actually do
- Check for the markers now. In any repository writable on or after 10 November: a wfx-docs branch, PRs titled "docs: dependency audit notes", commits titled "ci: refresh build cache", "chore: add ci helper" or "chore: add dependency audit workflow", short-lived chore/xxxxxxxx branches — and, most reliably, gaps in workflow-run numbering on attacker-touched commits. If the payload ran, assume every secret and cloud role available to those workflows is compromised.
- Rotate, then hunt for standing access. Rotate all exposed secrets and cloud credentials — but don't stop there. Audit branch-protection status checks for forged successes, AWS role trust policies for over-broad principals, and Entra application federated credentials for wfx-ci-… entries pointing at the compromised repository. These survive rotation by design.
- Treat installing machines as compromised. Anything that installed digitalelvis/neuronai-studio 3.14.3, and remove the two poisoned docker-env tags. Review private repositories too — the payload ships a private-repo configuration you cannot observe from outside.
- Break the credential-reuse chain. October GhostAction victims were ~1,000× more likely to be reused in November. Anyone remediating October by rotating tokens without clearing the developer-machine stealer (fa-solid-400.woff2, hidden VS Code task, #ghc2 cron job) and revoking sessions simply re-armed the November wave.
Our verification was read-only. We read the Aikido disclosure (Oliver Smith, published 12 November 2026) first-hand in full on 12 November 2026, including the affected-repository markers, all three delivery variants, the four-stage payload description, exfiltration endpoints and channel configuration, package findings, and the GhostAction-overlap non-attribution. Corroborating secondaries (The Hacker News, GBHackers, 12 November 2026) were carried as reported for scale figures only. We ran no payload, touched no repository, installed no package, and contacted no vendor. Brave Search was used for discovery only.
Sources:
- Aikido — Compromised GitHub accounts push CI secret stealer to tens of thousands of repositories (12 November 2026; read first-hand in full)
- The Hacker News — 4,837 Hijacked GitHub Accounts Ran a CI Secret Stealer in 1,806+ Repositories (12 November 2026; carried as reported)
- al-ice.ai — GhostAction October Wave: 30K Repositories, Blocked Runs, and the Campaign That Never Stopped
- al-ice.ai — The Trust Policy Outlived the Platform: Qubole Cross-Account Roles Abused to Raid Customer AWS