.png)
Introducing Secret Exfiltration Protection for GitHub Actions
StepSecurity breaks down how four campaigns, GhostAction, Megalodon, Miasma, and Hades, turned stolen GitHub tokens into mass secret theft by committing malicious GitHub Actions workflows to throwaway branches, using toJSON(secrets) to dump repo secrets and uploading them as run artifacts before deleting the branch and run. It explains why branch protection and code review miss this since the workflow runs on a push event to a non-default branch with no pull request ever opened, and introduces StepSecurity's Secret Exfiltration Policy plus a new Harden-Runner detection rule for the pattern.
What it is
StepSecurity's Secret Exfiltration Policy (configured under Workflow Run Policies), positioned against a shared "cash-out" step used by four GitHub Actions supply-chain campaigns: GhostAction, Megalodon, Miasma/Hades. The stolen developer token is only entry; the actual theft happens when the attacker commits a workflow that makes your own CI runner dump every secret and exfiltrate it as an artifact.
How it works (the attack)
The runner is the one place that legitimately holds all secrets at once, so the attacker turns it into the exfiltration tool. Hades:
- Clones the default branch, creates a throwaway branch named to blend in (e.g.
main4,master2). - Commits a workflow (named
Run Copilot, disguised under a real path like.github/workflows/codeql.yml) triggered onpush/deployment. - Loads
${{ toJSON(secrets) }}into an env var, writes it toformat-results.txt, uploads it as an artifact namedformat-results. - Polls the run, downloads the artifact, then deletes the run and the branch — no residue.
Branch protection and code review both only fire on pull requests into the default branch. Because no PR is opened and the default branch is never touched, both controls are structurally bypassed. Even under review, workflow YAML gets less scrutiny and steps pinned to commit SHAs read as hardened.
Hunt indicators (from the payload)
- Workflow/step names:
Run Copilot,Github Actions Security,SysDiag,Optimize-Build; step named "Copilot Setup". - Artifact name
format-results; fileformat-results.txt. - Short-lived branches (
main4,master2) with runs and branches deleted shortly after. - Any workflow referencing
toJSON(secrets).
What to do
Enable the Secret Exfiltration Policy under Workflow Run Policies. When on, a modified workflow in a non-default branch cannot use secrets unless explicitly approved — the run is canceled before any read, and a PR comment explains the block and approval path. Scope it per-repository or across the whole org. This directly covers the GhostAction/Megalodon/Hades scenario.
Caveats
The page describes a second detection layer that flags the exfiltration at runtime, but the fetched text is truncated before it is explained. The scale figures (GhostAction: 327 users / 817 repos / 3,325 secrets; Megalodon: 5,500+ repos in six hours; Miasma: 73 Azure-org repos disabled by GitHub) are StepSecurity's own reporting. Some dates are future-labeled (Megalodon May 2026, Miasma/Hades June 2026); treat the timeline as vendor-supplied.
Technologies named here
- StepSecurity GitHub App
- GitHub Actions
- npm tokens
- Secret Exfiltration Policy
- PyPI tokens
- Harden-Runner
- Secret Exfiltration Attempt detection
- DockerHub tokens
- Microsoft Azure organizations
- Notification Settings
- Claude Code
- Cursor
- VS Code
- StepSecurity
Techniques named here
- Stolen developer token used to commit malicious workflow
- Secret dump via toJSON
- Artifact-based exfiltration
- Branch protection bypass via non-default branch push
- Action pinning to commit SHAs to appear legitimate
- Evidence deletion
- Credential harvesting via AI coding tool configuration files
Threat actors named here
Related in DevSecOps
JFrog: The Governance Gap Between Your Policy and Your Pipeline

Dev Machine Guard Now Supports Windows - StepSecurity

Socket: TanStack npm Packages Compromised
