# Compromised GitHub Accounts Push CI Secret Stealer to Tens of Thousands of Repositories (November 2026 Wave)

> Beginning 2026-11-10 ~12:45 UTC, 4,837 compromised GitHub accounts opened probe pull requests titled 'docs: dependency audit notes' in 61,764 repositories and pushed payloads that steal GitHub Actions secrets and cloud credentials to attacker servers on port 8080 (/exfil). At least 1,806 repositories executed the payload, and at least 50 compromised users publish packages on npm, Go, Packagist, PyPI, or crates.

- **Published:** 2026-11-12T02:53:15Z
- **Last reviewed:** 2026-11-12T09:15:50.862Z
- **Canonical:** https://intel.threadlinqs.com/threat/TL-2026-5815
- **ID:** TL-2026-5815
- **Severity:** CRITICAL
- **Category:** SUPPLY_CHAIN
- **Status:** ACTIVE
- **Detections:** 9 (1 shown free below) · **IOCs:** 48 (3 shown free below)

## Description

Aikido Security reports a large-scale supply-chain campaign in which stolen GitHub tokens were used to act as legitimate accounts. Starting 2026-11-10 at about 12:45 UTC, 4,837 compromised accounts opened probe pull requests titled 'docs: dependency audit notes' from a branch named 'wfx-docs' in 61,764 repositories. The probe confirms write access; if it succeeds the account is treated as compromised even if the payload never runs. 10,431 of the probe PRs targeted repositories the account does not own, reached through collaborator or organization access, and about 92% of those remain open.

After a successful probe the actor pushes one of three payload variants. (1) Workflow injection, commit message 'ci: refresh build cache', adds roughly 1,500 lines to an existing workflow. (2) Install hook, commit message 'chore: add ci helper', adds a '.ci-xxxxxx.sh' script and a 'postinstall' hook in package.json that runs on any 'npm install'. (3) Throwaway branch, commit message 'chore: add dependency audit workflow', adds '.github/workflows/build-audit-xxxxxx.yml' on a 'chore/xxxxxxxx' branch. Injected steps include 'Pass runtime' (using actions/github-script@v7) and 'Restore cache j632'. The latter sets WF_CALLBACK (exfiltration URL), WF_CTOKEN (a hardcoded campaign token), WF_SECRETS (toJSON(secrets)) and WF_VARS (toJSON(vars)).

Targeted data includes GitHub Actions secrets and variables, the workflow GITHUB_TOKEN, Actions runtime and cache tokens, AWS/GCP/Azure credentials from instance metadata and OIDC, secrets in runner memory and environment variables (including AI provider API keys), repository contents and git history, the Actions cache, and build artifacts. Exfiltration goes to /exfil endpoints on port 8080 at 194.150.166.244 and 18.143.168.96; the source does not state the encoding. The actor reverts the change within about a minute and deletes the workflow run and its logs, so a gap in workflow run numbers may be the only trace. At least 1,806 repositories ran the payload and had credentials published; the true number is likely higher because run logs were deleted.

Overlap with the October 'GhostAction' wave is significant: accounts hit in October were about 1,000 times more likely than other active accounts to be used in November, and in more than 100 repositories the November payload was injected into October workflow files with the October exfiltration step left in place. October indicators include secret-scanning workflows (security-audit.yml, audit.yml, ci-check.yml) sending keys to 193.32.204.199, and a hidden VS Code task running JavaScript disguised as public/fonts/fa-solid-400.woff2 that steals ~/.git-credentials, SSH keys, and npm, PyPI, AWS and Claude credentials and installs a cron job tagged #ghc2 polling 193.32.204.199:8080. The source does NOT attribute the November wave to the same actor. Affected artifacts named by the source: Packagist digitalelvis/neuronai-studio 3.14.3 (treat any machine that installed or opened it as compromised) and Go module github.com/onuragtas/docker-env v1.0.278/v1.0.280 (payload only in a workflow file; Go source and binaries unchanged). Caveat: this is single-source vendor reporting; IOCs should be validated against additional sources. BeaconBeagle lookups for the three IPs returned HTTP 502 and could not be completed.

## MITRE ATT&CK

- T1195 Supply Chain Compromise
- T1195.002 Compromise Software Supply Chain
- T1078 Valid Accounts
- T1199 Trusted Relationship
- T1195.001 Compromise Software Dependencies and Development Tools
- T1053.003 Cron
- T1528 Steal Application Access Token
- T1059.004 Unix Shell
- T1059.007 JavaScript
- T1036.005 Match Legitimate Resource Name or Location
- T1552.001 Credentials In Files
- T1552.005 Cloud Instance Metadata API
- T1213.003 Code Repositories
- T1005 Data from Local System
- T1071.001 Web Protocols
- T1098.001 Additional Cloud Credentials
- T1070 Indicator Removal
- T1550.001 Use Alternate Authentication Material
- T1526 Cloud Service Discovery
- T1119 Automated Collection
- T1560.001 Archive Collected Data
- T1041 Exfiltration Over C2 Channel
- T1567 Exfiltration Over Web Service
- T1586 Compromise Accounts
- T1003.007 OS Credential Dumping: Proc Filesystem
- T1078.004 Valid Accounts
- T1036 Masquerading
- T1562 Impair Defenses
- T1552.003 Unsecured Credentials
- T1552.004 Unsecured Credentials

## Free detection (Splunk SPL, Microsoft KQL, Sigma)

**GitHub Probe PR / Payload Commit Markers from Compromised Account — Exploitation** (`TL-2026-5815-SPL-001`)

Detects the November 2026 GitHub Actions secret-stealer wave (TL-2026-5815) at the repository-event layer: the probe pull request titled 'docs: dependency audit notes' from branch wfx-docs, the three payload commit messages ('ci: refresh build cache', 'chore: add ci helper', 'chore: add dependency audit workflow') and a build-audit workflow file on a throwaway chore/<8 char> branch. Aggregated per actor so one compromised token touching many repositories stands out. Requires GitHub audit/webhook (push, pull_request) events indexed in Splunk.

- **Languages:** Splunk SPL, Microsoft KQL, Sigma
- **ATT&CK:** T1195, T1195.002, T1078, T1199
- **Data sources:** github:cloud:audit, github:enterprise:audit, GitHubAuditLogPolling_CL, github audit log
- **Severity:** high
- **Confidence:** high

### Splunk SPL

````spl
index=github sourcetype IN ("github:cloud:audit","github:enterprise:audit") ```TL-2026-5815 probe PR and payload commit markers``` | eval raw=lower(_raw) | eval probe_pr=if(match(raw,"docs: dependency audit notes") OR match(raw,"wfx-docs"),1,0), payload_commit=if(match(raw,"ci: refresh build cache|chore: add ci helper|chore: add dependency audit workflow"),1,0), throwaway_wf=if(match(raw,"chore/[a-z0-9]{8}") AND match(raw,"build-audit-[a-z0-9]+[.]yml"),1,0) | where probe_pr=1 OR payload_commit=1 OR throwaway_wf=1 | eval actor=coalesce(actor,user,"unknown"), repo=coalesce(repo,repository,"unknown") | stats count earliest(_time) as first_seen latest(_time) as last_seen dc(repo) as repos_touched values(action) as actions max(probe_pr) as probe_pr max(payload_commit) as payload_commit max(throwaway_wf) as throwaway_wf by actor | eval first_seen=strftime(first_seen,"%F %T"), last_seen=strftime(last_seen,"%F %T") | sort - repos_touched | table actor repos_touched count actions probe_pr payload_commit throwaway_wf first_seen last_seen
````

### Microsoft KQL

```kql
GitHubAuditLogPolling_CL | where TimeGenerated > ago(24h) | extend raw = tolower(tostring(pack_all())) | extend probe_pr = raw contains 'docs: dependency audit notes' or raw contains 'wfx-docs', payload_commit = raw contains 'ci: refresh build cache' or raw contains 'chore: add ci helper' or raw contains 'chore: add dependency audit workflow', throwaway_wf = (raw matches regex 'chore/[a-z0-9]{8}' and raw matches regex 'build-audit-[a-z0-9]+[.]yml') | where probe_pr or payload_commit or throwaway_wf | extend Actor = tostring(coalesce(column_ifexists('actor_s',''), column_ifexists('actor_login_s',''))), Repo = tostring(column_ifexists('repo_s','')), Action = tostring(column_ifexists('action_s','')) | summarize Events=count(), FirstSeen=min(TimeGenerated), LastSeen=max(TimeGenerated), Repos=dcount(Repo), Actions=make_set(Action, 20) by Actor, probe_pr, payload_commit, throwaway_wf | order by Repos desc
```

### Sigma

```yaml
title: TL-2026-5815 GitHub Probe PR or Payload Commit Markers from Compromised Account
id: 6b0f2a1e-3c4d-4e57-9a18-5d2c7e9b4f10
status: experimental
description: |
    Detects the November 2026 GitHub Actions secret-stealer wave. Keywords match the probe pull request title
    'docs: dependency audit notes', the wfx-docs probe branch and the three payload commit messages pushed after a
    successful write-access probe.
references:
    - https://www.aikido.dev/blog/compromised-github-accounts-push-ci-secret-stealer-to-tens-of-thousands-of-repositories
author: Threadlinqs Team
date: 2026-11-12
tags:
    - attack.initial-access
    - attack.t1078
    - attack.t1199
    - attack.t1195.002
logsource:
    product: github
    service: audit
detection:
    keywords:
        - 'docs: dependency audit notes'
        - 'wfx-docs'
        - 'ci: refresh build cache'
        - 'chore: add ci helper'
        - 'chore: add dependency audit workflow'
    condition: keywords
falsepositives:
    - Legitimate documentation pull requests that reuse the same title or branch name
    - Internal tooling that uses the same commit message conventions
level: high

```

**Known false positives:**

- Legitimate documentation pull requests that happen to reuse the title 'docs: dependency audit notes' or a branch named wfx-docs
- Internal security tooling that adds audit workflows on chore/ branches or uses the same commit message conventions

**Tuning notes:** Confirm PR/push webhook events (not only the audit log) are ingested, since PR titles and commit messages are not in every audit stream. Field names (actor, repo, action) vary by connector, so adjust the coalesce() lists. Allow-list known automation accounts. Treat any hit on the exact PR title plus the wfx-docs branch as a confirmed token compromise and rotate that account's tokens.

### 8 more detection rules (Splunk SPL, Microsoft KQL, Sigma), unlock with TL Creds

- Campaign Workflow File or Helper Script Written to Endpoint — Exploitation (locked: unlock with TL Creds)
- GhostAction-Linked #ghc2 Cron Persistence Polling [indicator]:8080 — Post-Exploitation (locked: unlock with TL Creds)
- HTTP Exfiltration to /exfil on Port 8080 and Legacy GhostAction Infrastructure — C2 / Exfiltration (locked: unlock with TL Creds)
- Install of Compromised neuronai-studio 3.14.3 or docker-env v1.0.278/v1.0.280 — Exploitation (locked: unlock with TL Creds)
- Credential, Cloud Metadata and Git History Harvesting by node/shell — Post-Exploitation (locked: unlock with TL Creds)
- CI Runner Process Using Campaign Callback, WF_* Variables or Hardcoded Token — C2 / Exfiltration (locked: unlock with TL Creds)
- CI Helper Script via postinstall and Disguised woff2 JavaScript Execution — Post-Exploitation (locked: unlock with TL Creds)
- Egress to Campaign Exfiltration Servers on TCP 8080 — C2 / Exfiltration (locked: unlock with TL Creds)

Sign up free to unlock the detection rules: https://threadlinqs.com/?modal=signup

## Sample indicators (3 of 48)

Defanged, TLP:CLEAR.

- IP address: `194.150.166[.]244`
- Domain: `carte-avantage[.]com`
- File hash: `89695abb392d5cfd4972672961e644bb46baa98aa1ed7173c2a2816c762735cf`

Full set of 48 indicators unlocks with TL Creds: https://threadlinqs.com/tl-creds

## Sources

- [Compromised GitHub accounts push CI secret stealer to tens of thousands of repositories (Aikido Security)](https://www.aikido.dev/blog/compromised-github-accounts-push-ci-secret-stealer-to-tens-of-thousands-of-repositories)
- [GhostAction campaign: secrets stolen through malicious GitHub workflows (StepSecurity)](https://www.stepsecurity.io/blog/ghostaction-campaign-over-3-000-secrets-stolen-through-malicious-github-workflows)
- [GhostAction Returns (StepSecurity)](https://www.stepsecurity.io/blog/ghostaction-returns)
- [GhostAction campaign: 3,325 secrets stolen (GitGuardian)](https://blog.gitguardian.com/ghostaction-campaign-3-325-secrets-stolen/)
- [GhostAction Hacking Wave Fizzles, But Attackers Lurk on in GitHub (Dark Reading)](https://darkreading.com/application-security/ghostaction-hacking-wave-fizzles-attackers-github)
- [Hackers hijacked 1,900 GitHub accounts then went after 30,000 repos (The New Stack)](https://thenewstack.io/hackers-hijacked-1900-github-accounts-then-they-went-after-30000-repos/)
- [GitHub workflows attack affects hundreds of repos, thousands of secrets (SecurityWeek)](https://www.securityweek.com/github-workflows-attack-affects-hundreds-of-repos-thousands-of-secrets/amp/)
- [CSA research note: GitHub Actions workflow credential theft](https://labs.cloudsecurityalliance.org/wp-content/uploads/2026/10/CSA_research_note_github_actions_workflow_credential_theft_20261012-csa-styled.pdf)

## Full data

The other 8 detection rules (Splunk SPL / Microsoft KQL / Sigma) unlock with TL Creds; a free account includes daily creds: https://threadlinqs.com/?modal=signup
Indicator values unlock with TL Creds, at a lower price on Red and Purple; AI agents can query rules and IOCs through the Threadlinqs MCP server (Purple): https://intel.threadlinqs.com/mcp

Canonical: https://intel.threadlinqs.com/threat/TL-2026-5815
