Between October 8 and 9, 2026, GitGuardian researchers observed a sharp spike in the GhostAction credential-theft campaign — a coordinated operation that has now compromised approximately 1,900 GitHub accounts, touched more than 30,000 repositories, and reached across 3,000 users and organizations. According to researcher Gaetan and the GitGuardian team, the operators used those hijacked accounts in an attempt to extract 3,174 secrets from public repositories' CI pipelines.
Let that sink in: this is not a vulnerability in GitHub. There is no CVE to patch. This is large-scale account takeover weaponized against your software supply chain — the credentials, tokens, and signing keys that live in your CI/CD environment. If a single cloud provider key, npm token, or code-signing certificate was exposed in a pipeline log or workflow run, an attacker now owns a foothold into your build system, your artifact registry, and potentially your production environment.
Every organization with a GitHub footprint — public or private — should treat this as an active incident until proven otherwise.
Technical Analysis: How GhostAction Operates
Attack Chain
Based on the campaign's observed behavior, the kill chain looks like this:
- Credential acquisition — The operators harvest GitHub credentials (passwords, session tokens, personal access tokens) through infostealer malware, phishing kits, and credential-stuffing against previously breached password corpuses. Accounts without enforced two-factor authentication are the softest targets.
- Account takeover — Valid credentials are replayed against GitHub, often from IP ranges and ASN geographies inconsistent with the victim's history. Attackers frequently add their own SSH keys or register new personal access tokens (PATs) to persist beyond a password reset.
- Repository reconnaissance at scale — With 30,000+ repositories targeted, this is automated. Compromised accounts enumerate org membership, clone or download repositories, and enumerate Actions workflow runs.
- CI secret extraction — The campaign specifically targeted secrets accessible through CI contexts: workflow run logs, environment variables echoed during builds, misconfigured workflows that print secrets on failure, and
.envfiles or credentials committed to repository history. GitGuardian's count of 3,174 attempted secret extractions reflects systematic scanning, not opportunistic browsing. - Monetization and pivot — Stolen cloud keys (AWS, Azure, GCP), package registry tokens, and signing credentials enable downstream supply-chain compromise, cryptomining, data theft, and resale.
Why CI Pipelines Are the Prize
CI/CD runners are credential concentrators. A GitHub Actions runner executing a workflow holds, in memory and environment variables, every secret the workflow needs: deployment keys, registry tokens, cloud session credentials. When developers (or compromised accounts) trigger workflows on attacker-controlled code — or when secrets leak into logs via debugging output, env dumps, or error traces — those credentials are exposed in plaintext. Public repositories amplify the risk because workflow logs on public repos are world-readable.
Exploitation Status
- Actively exploited in the wild: Yes. Confirmed mass campaign with observed spike October 8–9, 2026.
- CVE: None — this is credential abuse and configuration exploitation, not a software flaw.
- CISA KEV: Not applicable, but the underlying techniques map to MITRE ATT&CK T1078 (Valid Accounts), T1552 (Unsecured Credentials), and T1557 (Adversary-in-the-Middle, for token theft).
Detection & Response
Your detection strategy needs two layers: GitHub platform telemetry (audit logs, authentication events) and developer endpoint telemetry (credential file access, infostealer behavior that feeds this pipeline).
Sigma Rules
---
title: GitHub Audit Log Persistence Events - SSH Key or Token Creation
description: Detects creation of SSH keys, personal access tokens, or OAuth authorizations in GitHub audit logs, a common persistence mechanism after account takeover as seen in GhostAction.
references:
- https://thehackernews.com/2026/10/ghostaction-compromises-about-1900.html
- https://attack.mitre.org/techniques/T1098/
author: Security Arsenal
date: 2026/10/12
status: experimental
id: 8f2c1b7a-4d9e-4a3b-9c6f-2e8a1d5b7c9e
tags:
- attack.persistence
- attack.t1098
logsource:
product: github
service: audit
detection:
selection:
action:
- 'ssh_key.create'
- 'ssh_key.create_verified'
- 'personal_access_token.create'
- 'oauth_authorization.create'
- 'public_key.create'
- 'deploy_key.create'
condition: selection
falsepositives:
- Developers legitimately adding keys or tokens - correlate with source IP geography, impossible travel, and recent password change events
level: high
---
title: GitHub Mass Repository Access or Cloning from Single Identity
description: Detects bulk repository clone, download, or fork events from a single user in GitHub audit logs, consistent with automated reconnaissance observed in the GhostAction campaign.
references:
- https://thehackernews.com/2026/10/ghostaction-compromises-about-1900.html
- https://attack.mitre.org/techniques/T1213/
author: Security Arsenal
date: 2026/10/12
status: experimental
id: 3e7a9c2d-1b4f-4e8a-a5d6-9f1c3b7e2a4d
tags:
- attack.collection
- attack.t1213
logsource:
product: github
service: audit
detection:
selection:
action:
- 'repo.clone'
- 'repo.download_zip'
- 'repo.archive'
- 'git.clone'
condition: selection
falsepositives:
- CI/CD systems and backup tooling performing scheduled bulk clones - whitelist known automation accounts and runner IPs
level: medium
---
title: Credential File Access on Developer Workstations
description: Detects suspicious access to git credential stores, SSH private keys, or cloud CLI credential files by processes that should not touch them, a precursor to the infostealer-to-account-takeover pipeline feeding GhostAction.
references:
- https://thehackernews.com/2026/10/ghostaction-compromises-about-1900.html
- https://attack.mitre.org/techniques/T1552/
author: Security Arsenal
date: 2026/10/12
status: experimental
id: 5b1d8e3f-7c2a-4f6d-b9e4-1a8c5d3f6e2b
tags:
- attack.credential_access
- attack.t1552.001
logsource:
category: file_event
product: windows
detection:
selection_paths:
TargetFilename|contains:
- '\.git-credentials'
- '\.ssh\id_rsa'
- '\.ssh\id_ed25519'
- '\.aws\credentials'
- '\.azure\accessTokens.json'
- '\AppData\Roaming\GitHub Desktop\'
- '\.config\gh\hosts.yml'
filter_benign:
Image|endswith:
- '\git.exe'
- '\ssh.exe'
- '\gh.exe'
- '\GitHubDesktop.exe'
- '\Code.exe'
- '\aws.exe'
- '\az.exe'
condition: selection_paths and not filter_benign
falsepositives:
- Backup software and DLP agents scanning user profiles - tune against your approved tooling
level: high
KQL Hunt Queries (Microsoft Sentinel / Defender)
The first query assumes you ingest GitHub audit logs into Sentinel (via the GitHub connector or a custom webhook pipeline into a GitHubAuditLog / GitHubAuditLog_CL table — adjust the table name to your deployment). The second hunts developer endpoints via Defender for Endpoint.
// Hunt 1: GitHub persistence + anomalous access after GhostAction campaign window
// Detects new SSH keys/PATs created, followed by bulk repo access from the same user
let campaign_start = datetime(2026-10-01);
let persistence_events = GitHubAuditLog
| where TimeGenerated >= campaign_start
| where action in ("ssh_key.create", "personal_access_token.create", "oauth_authorization.create", "public_key.create", "deploy_key.create")
| project actor, actor_ip, action, created_at=TimeGenerated, repo;
let bulk_access = GitHubAuditLog
| where TimeGenerated >= campaign_start
| where action in ("repo.clone", "repo.download_zip", "git.clone", "repo.archive")
| summarize clone_count=count(), repos_touched=dcount(repo), first_ip=any(actor_ip) by actor, bin(TimeGenerated, 1h)
| where clone_count > 25 or repos_touched > 15;
bulk_access
| join kind=leftouter persistence_events on actor
| project actor, TimeGenerated, clone_count, repos_touched, first_ip, persistence_action=action, persistence_ip=actor_ip, persistence_time=created_at
| sort by clone_count desc;
// Hunt 2: Defender for Endpoint - suspicious processes touching git/SSH/cloud credential stores
let cred_paths = dynamic(["\\.git-credentials", "\\.ssh\\id_", "\\.aws\\credentials", "\\.config\\gh\\hosts.yml", "accessTokens.json"]);
DeviceFileEvents
| where TimeGenerated >= ago(14d)
| where FolderPath has_any (cred_paths)
| where not (InitiatingProcessFileName in~ ("git.exe", "ssh.exe", "gh.exe", "GitHubDesktop.exe", "Code.exe", "aws.exe", "az.exe", "MsMpEng.exe"))
| project TimeGenerated, DeviceName, InitiatingProcessFileName, InitiatingProcessCommandLine, FolderPath, FileName, AccountName
| sort by TimeGenerated desc;
Velociraptor VQL
Use this artifact to sweep developer workstations for evidence of credential-store access and recently planted persistence artifacts (newly authorized keys in git config or altered credential helpers).
-- GhostAction Triage: Enumerate git credential stores, gh CLI tokens, and SSH keys
-- with modification timestamps to identify files touched during the campaign window
SELECT FullPath,
Mtime,
Atime,
Size,
Mtime < "2026-10-01" AS ModifiedBeforeCampaign
FROM glob(globs=[
"C:/Users/*/.git-credentials",
"C:/Users/*/.config/gh/hosts.yml",
"C:/Users/*/.ssh/id_*",
"C:/Users/*/.aws/credentials",
"/home/*/.git-credentials",
"/home/*/.config/gh/hosts.yml",
"/home/*/.ssh/id_*",
"/Users/*/.git-credentials",
"/Users/*/.config/gh/hosts.yml"
])
WHERE NOT IsDir
ORDER BY Mtime DESC
Remediation / Audit Script
This Bash script uses the GitHub CLI (gh) to audit an organization for the exact persistence and exposure patterns GhostAction exploits: members without 2FA, recent key/token events in the audit log, and secrets scanning alerts.
#!/bin/bash
# GhostAction Post-Compromise Org Audit - requires gh CLI authenticated with org admin scope
set -euo pipefail
ORG="${1:?Usage: $0 <org-name>}"
REPORT="ghostaction_audit_$(date +%Y%m%d).txt"
echo "=== GhostAction Org Audit: $ORG ===" | tee "$REPORT"
# 1. List org members WITHOUT two-factor authentication - primary takeover surface
echo -e "\n[1] Members without 2FA enforced:" | tee -a "$REPORT"
gh api "/orgs/$ORG/members?filter=2fa_disabled&per_page=100" --jq '.[].login' | tee -a "$REPORT"
# 2. Pull audit log for persistence events in the campaign window
echo -e "\n[2] SSH key / token creation events since Oct 1 2026:" | tee -a "$REPORT"
gh api "/orgs/$ORG/audit-log?phrase=created:>2026-10-01+action:ssh_key.create&per_page=100" \
--jq '.[] | "\(.created_at) \(.actor) \(.action) from \(.actor_ip)"' | tee -a "$REPORT" || true
gh api "/orgs/$ORG/audit-log?phrase=created:>2026-10-01+action:personal_access_token.create&per_page=100" \
--jq '.[] | "\(.created_at) \(.actor) \(.action) from \(.actor_ip)"' | tee -a "$REPORT" || true
# 3. Flag failed logins + successful logins from unusual sources
echo -e "\n[3] Authentication anomalies since Oct 1 2026:" | tee -a "$REPORT"
gh api "/orgs/$ORG/audit-log?phrase=created:>2026-10-01+action:user.login&per_page=100" \
--jq '.[] | "\(.created_at) \(.actor) from \(.actor_ip)"' | sort | uniq -c | sort -rn | head -30 | tee -a "$REPORT" || true
# 4. Enumerate repos with Actions enabled (secret exposure surface) and secret scanning alerts
echo -e "\n[4] Repos with open secret-scanning alerts:" | tee -a "$REPORT"
for REPO in $(gh repo list "$ORG" --limit 200 --json nameWithOwner --jq '.[].nameWithOwner'); do
ALERTS=$(gh api "/repos/$REPO/secret-scanning/alerts?state=open" --jq 'length' 2>/dev/null || echo "n/a")
[ "$ALERTS" != "0" ] && [ "$ALERTS" != "n/a" ] && echo "$REPO: $ALERTS open secret alerts" | tee -a "$REPORT"
done
echo -e "\nAudit complete. Review $REPORT, then: rotate all org secrets, revoke unverified PATs/SSH keys, enforce 2FA." | tee -a "$REPORT"
Remediation: What to Do in the Next 24–72 Hours
Immediate (Containment)
- Force-rotate every secret reachable from CI. If GhostAction extracted 3,174 secrets across public repos, assume yours are in the pile. Rotate cloud keys, registry tokens (npm, PyPI, Docker Hub, NuGet), signing keys, and database credentials — in that priority order. GitGuardian maintains a public checker; also review GitHub secret scanning alerts for your org.
- Revoke all personal access tokens and SSH keys created after October 1, 2026 unless individually verified with the owning user. Audit log actions to review:
ssh_key.create,personal_access_token.create,oauth_authorization.create,deploy_key.create. - Enforce 2FA at the organization level immediately (GitHub org Settings → Authentication security → Require two-factor authentication). Prefer phishing-resistant methods (FIDO2/passkeys) over SMS/TOTP where feasible.
- Expire active sessions. Password reset alone does not kill hijacked session cookies. Use
user.revoke_sessionsvia admin controls or have users sign out all sessions from their security settings.
Short Term (Hardening CI/CD)
- Audit workflow logs for secret exposure. Search Actions run logs for printed environment variables, base64 blobs, and error traces containing credential material. Delete affected runs and rotate anything found.
- Lock down Actions permissions: set
GITHUB_TOKENto read-only by default, require approval for workflows from forks, disable Actions on repos that don't need them, and pin third-party actions to full commit SHAs. - Move secrets out of repository contexts into OIDC-based short-lived credentials (e.g., GitHub OIDC to AWS/Azure/GCP) so there is no long-lived secret to steal in the first place.
- Enable and alert on secret scanning + push protection for all repos, including private ones.
Strategic (Detection Engineering)
- Ship GitHub audit logs to your SIEM and deploy the Sigma/KQL detections above. Alert on impossible travel, key/token creation from new geographies, and bulk clone behavior.
- Baseline developer endpoint hygiene: infostealers are the upstream feeder for campaigns like this. Ensure EDR coverage on engineering workstations and hunt for credential-store access (see Sigma rule 3 and the VQL artifact).
- Monitor for your org's secrets in the wild. GitGuardian's public monitoring and similar services will flag your keys appearing in commits or dark-web dumps — wire those alerts into your IR queue.
Vendor References
- GitHub audit log documentation: https://docs.github.com/en/organizations/keeping-your-organization-secure/reviewing-the-audit-log-for-your-organization
- GitHub 2FA enforcement: https://docs.github.com/en/organizations/keeping-your-organization-secure/requiring-two-factor-authentication-in-your-organization
- GitHub OIDC for cloud credentials: https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/about-security-hardening-with-openid-connect
- GitGuardian GhostAction reporting: https://thehackernews.com/2026/10/ghostaction-compromises-about-1900.html
The Bottom Line
GhostAction is not exotic. It is industrial-scale credential theft pointed at the softest, highest-value target in modern engineering: the CI pipeline. The defenders who weather this campaign are the ones who (a) enforce phishing-resistant MFA, (b) eliminate long-lived secrets from CI via OIDC, and (c) actually ingest and alert on their GitHub audit logs. If you're compromised or unsure, treat it as an incident: rotate first, investigate second.
Related Resources
Security Arsenal Managed SOC Services AlertMonitor Platform Book a SOC Assessment soc-mdr Intel Hub
Is your security operations ready?
Get a free SOC assessment or see how AlertMonitor cuts through alert noise with automated triage.