Contents
ToggleExecutive Summary
Automated mass commits are replacing legitimate GitHub Actions workflow files with a malicious version named “Optimize-Build.” When the poisoned workflow runs, it decodes and executes a bash credential harvester. The script drains every secret the runner can reach: AWS keys across all configured profiles, GCP OAuth tokens, SSH private keys, GitHub OIDC tokens, kubeconfig, Terraform and Vault credentials, Docker registry auth, package registry tokens, and cloud instance metadata queried from AWS, GCP, and Azure IMDS endpoints — all in a single execution.

This campaign has no CVE. No scanner fires on it. The payload is a base64-encoded shell script injected directly into a workflow YAML file. Every tool that monitors packages and libraries is blind to it. Catching it requires workflow file integrity monitoring, GitHub audit log analysis, or network egress anomaly detection on CI runners.
Each compromised repository gets a unique device ID embedded in the payload at injection time. All exfiltration routes to a C2 server at 216.126.225.129:8443 under the campaign identifier “megalodon.” GitHub code search on the payload base64 prefix (Q0I9Imh0dHA6Ly8yMTYu) returned over 3,500 infected YAML files at time of writing, with an alleged total of 5,000+ repositories reported by OX Security. The two initially confirmed repositories are from unrelated organisations — a commercial live chat platform and a personal geolocation project — confirming automated iteration across a corpus of stolen GitHub tokens or OAuth grants.

OX Security has explicitly linked this campaign to the preceding TeamPCP GitHub breach, framing MEGALODON as a second wave that followed once attacker access to GitHub infrastructure was established.
TL;DR for Engineering Teams
| Field | Detail |
|---|---|
| What it is | Active zero-CVE campaign. Automated mass commits replace GitHub Actions workflow files with a credential harvester. No CVE, no CVSS score, no package IOC. |
| Where it bites | Any GitHub repository where the attacker has write access. 3,500+ infected repos confirmed via GitHub code search; 5,000+ alleged total (OX Security, May 2026). Every runner executing a poisoned workflow loses all accessible secrets. |
| Why it matters | Zero scanner coverage. The payload targets AWS IMDS, GCP metadata, Azure IMDS, and OIDC tokens — full cloud credential exfiltration in one execution, across all three major cloud providers simultaneously. |
| Patch status | No patch — this is not a software vulnerability. Requires access revocation, workflow revert, and full secrets rotation. |
| Immediate action | Audit all .github/workflows/ files for base64 -d | bash. Rotate all secrets accessible from any runner that ran a modified workflow. Block 216.126.225.129 at network egress. |
Vulnerability Overview
| Field | Detail |
|---|---|
| Vendor | GitHub / affected repository owners |
| Product | GitHub Actions CI/CD workflows |
| Vulnerability Type | CI/CD workflow poisoning — credential harvesting |
| CWE | CWE-94 (Code Injection), CWE-522 (Insufficiently Protected Credentials), CWE-312 (Cleartext Storage of Sensitive Information), CWE-829 (Inclusion from Untrusted Control Sphere) |
| CVSS Score | N/A — No CVE assigned. Qualitative: Critical |
| CVE | None — Zero-CVE supply chain campaign |
| Patch Available | No — requires access remediation and secrets rotation |
| Active Exploitation | Confirmed — automated mass commits observed May 2026 |
| C2 Infrastructure | 216.126.225.129:8443 (campaign identifier: megalodon) |
| Campaign Status | Active — investigation ongoing, attribution unconfirmed |
Technical Anatomy
Root Cause
There is no software vulnerability here. GitHub Actions works exactly as designed: any workflow file committed to a repository runs on the runner with whatever permissions it requests. The attacker gains write access via a stolen PAT, OAuth grant, or compromised account, commits a replacement workflow, and the runner executes it cleanly. The runner has no way to know the workflow was swapped.
GitHub has no built-in enforcement for workflow file integrity. Nothing in the platform detects that a workflow was replaced with a malicious version. Nothing requires cryptographic signing of workflow content. Nothing alerts when a workflow suddenly requests id-token: write — a permission most standard workflows never need. The attacker added that permission deliberately. It unlocks OIDC token generation, and its presence in any replacement workflow is the clearest available signal that something is wrong.

Three-Step Exploit Path
| Step | Phase | Detail |
|---|---|---|
| 1 | Entry Point | Attacker commits a replacement workflow file to the target repository using a compromised PAT, OAuth token, or GitHub account with write access. The file is renamed “Optimize-Build” and the job renamed “check”. The id-token: write permission is added. All original build steps are stripped and replaced with a single run: step containing a base64-encoded bash payload. |
| 2 | Trigger | When the workflow runs — via workflow_dispatch, on push, or on pull request — the runner executes: set +e; echo "[payload]" | base64 -d | bash. The payload decodes in memory (nothing written to disk before execution), initialises per-campaign variables including a unique device ID and C2 callback URL, then begins harvesting. |
| 3 | Execution Impact | The harvester exfiltrates all environment variables, credential files (AWS, SSH, GCP, kube, Terraform, Vault, Docker, npm, git), CI/CD tokens (GITHUB_TOKEN, ACTIONS_ID_TOKEN, CI_JOB_JWT_V2, BITBUCKET_TOKEN), source code regex matches for credential patterns, and cloud IMDS credentials from AWS, GCP, and Azure simultaneously. All data is POST-exfiltrated to 216.126.225.129:8443. Temporary artifacts are deleted on exit via trap. |

Attack Chain — Phases
Phase 1 — Access Acquisition Attacker obtains write access to GitHub repository via stolen PAT, OAuth grant abuse, or compromised account credential.
Phase 2 — Workflow Injection Automated tooling commits replacement workflow files. All workflow files in .github/workflows/ are targeted. Each injected file receives a unique device ID embedded in the payload. Commits use a hardcoded fake identity — ci-bot@automated.dev or build-system@noreply.dev, dated September 17, 2001 — mirroring TeamPCP use of a fabricated commit date to obscure timing.
Phase 3 — Credential Harvest On next workflow execution, the runner exfiltrates: all environment variables, 28+ credential file paths, AWS CLI profile enumeration, GCP token extraction, source file grep for credential patterns (150 files, 29 file types), OIDC token generation, and all three cloud IMDS endpoints. The credential pattern search explicitly targets AWS keys, Slack tokens, GitHub tokens, PyPI tokens, and npm tokens. Slack token inclusion is notable — it suggests the attacker expects active Slack workspace tokens to be accessible in developer and CI environments.
Phase 4 — Durable Access Harvested SSH keys, long-lived IAM credentials, and git tokens give the attacker repository and cloud access that persists beyond the initial compromise and survives a simple workflow revert.
There is a regex of the second-layer base64 regex confirms the credential pattern search explicitly targets AWS keys, Slack tokens, GitHub tokens, PyPI tokens, and npm tokens alongside generic secret patterns. Slack tokens are not commonly included in harvester tooling of this type — their presence suggests the attacker expects active Slack workspace tokens to be accessible in developer and CI environments.
Affected Scope
| Component | Vulnerable Condition | Fixed Version | Notes |
|---|---|---|---|
| GitHub Actions workflow files | Any .github/workflows/*.yml with base64-encoded run: step | N/A — remove malicious file, revert to clean commit | All workflow files in the repository are targeted |
| GitHub Actions runners (hosted) | Executes a poisoned workflow with any CI/CD secrets in scope | N/A — rotate all accessible secrets post-execution | Ephemeral runners — no host persistence |
| GitHub Actions runners (self-hosted) | Executes a poisoned workflow; filesystem persistence possible | N/A — rotate secrets, audit runner filesystem | Higher risk: non-ephemeral, may retain harvested artifacts |
| OIDC-connected cloud accounts (AWS/GCP/Azure) | Runner has id-token: write; OIDC trust configured | Revoke and reissue OIDC trust relationships | Short-lived tokens exfiltrated and usable within validity window |
| Cloud instances with IMDS access | Runner deployed in AWS, GCP, or Azure with metadata service accessible | N/A — restrict IMDS access from CI runners | IMDSv2 is queried; IAM role credentials exfiltrated if present |
Exposure Analysis
| Environment | Risk Level | Reason |
|---|---|---|
| Repositories with cloud deployment secrets | CRITICAL | AWS/GCP/Azure access keys in runner scope exfiltrated immediately via printenv |
| Repositories with OIDC to cloud | CRITICAL | id-token: write grants OIDC token generation — attacker can impersonate the runner identity at cloud provider |
| CI/CD pipelines with package registry tokens | HIGH | npm, PyPI, Docker Hub tokens exfiltrated — downstream supply chain poisoning risk |
| Cloud-hosted runners (AWS/GCP/Azure) | HIGH | IMDS endpoint queries extract IAM role credentials, managed identity tokens regardless of repository secrets |
| Repositories with SSH deploy keys | HIGH | ~/.ssh/ directory fully exfiltrated — SSH private keys enable persistent repository and server access |
| Developer machine / local runner environments | HIGH | Shell history, git credentials, Vault tokens, and kubeconfig all harvested if present on runner filesystem |
GitHub code search on the payload prefix returned 3,500+ infected YAML files in public repositories. That number is expected to grow — the campaign is active and the attack toolchain is automated. Private repository exposure is harder to quantify from the outside, but the blast radius is larger: private repos are more likely to hold production secrets, cloud deployment credentials, and infrastructure access.
Protect yourself with the latest threat intelligence, get access to PHOENIX BLUE Today
Real-World Impact: Confirmed Compromises
| Repository | Workflow Targeted | Device ID |
|---|---|---|
| Tiledesk/tiledesk-server | docker-community-worker-push-latest.yml | hefs8esnhgkx |
| Davidf2004/Proyecto-GEOREFERENCIADOS | docker-publish.yml | 4ny72dgixww6 |
Tiledesk had multiple workflow files compromised in the same campaign. The attacker iterated through all files in .github/workflows/, not just the primary one. The per-repository device IDs confirm automated tooling generating unique per-target payloads at injection time.
Attack Scenarios
Scenario A — Repository with AWS deployment secrets: The attacker gets AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, and AWS_SESSION_TOKEN from the printenv dump within seconds of the workflow running. Long-lived IAM user credentials expire when rotated, not on a schedule.
Scenario B — Runner with OIDC to AWS: ACTIONS_ID_TOKEN_REQUEST_URL and ACTIONS_ID_TOKEN_REQUEST_TOKEN are exfiltrated. The attacker calls the OIDC endpoint directly and gets a short-lived AWS session token within the validity window, typically minutes. Rotating repository secrets alone does not close this. The OIDC trust configuration in AWS must be revoked and rebuilt from scratch.
Scenario C — GCP-connected runner: gcloud auth print-access-token returns an active GCP OAuth2 access token. Combined with the full GCP IMDS dump, the attacker has project-level API access across every service the service account was granted.
Scenario D — Package registry compromise: npm, PyPI, or Docker Hub tokens exfiltrated from ~/.npmrc, ~/.pypirc, or ~/.docker/config.json let the attacker publish under the organisation’s registry identity. A CI credential theft becomes a supply chain attack on everyone downstream.
Detection Guidance
Log Indicators
- GitHub Audit Log: commits to
.github/workflows/fromci-bot@automated.devandbuild-system@noreply.dev - Git log: commits dated September 17, 2001 in any workflow file path:
git log --before="2002-01-01" -- .github/workflows/ - GitHub Actions run logs: jobs named “check” running base64 commands in
run:steps - Network egress logs: POST requests carrying
X-Mega-DID,X-Mega-Plat, orX-Mega-Fileheaders - AWS CloudTrail / GCP Audit Log: credential use from unexpected IPs or user-agent strings containing
curlfollowing a CI run
IOC Table
| Category | Indicator | Notes |
|---|---|---|
| IP Address | 216[.]126[.]225[.]129 | C2 exfiltration server |
| Port | 8443 | Non-standard HTTPS |
| URL | hxxp://216[.]126[.]225[.]129:8443?h=megalodon | C2 beacon base URL |
| HTTP Param | h=megalodon | Campaign identifier in every exfil request |
| HTTP Header | X-Mega-DID | Device ID per compromised repository |
| HTTP Header | X-Mega-Plat | Platform tag (gh = GitHub) |
| HTTP Header | X-Mega-File | Logical filename of exfiltrated artifact |
| Workflow Name | Optimize-Build | Malicious replacement workflow display name |
| Job Name | check | Malicious job name within replacement workflow |
| Permission | id-token: write | Added by attacker to enable OIDC harvest |
| Shell Pattern | set +e; echo "..." | base64 -d | bash | Detectable in workflow YAML |
| Commit Author | ci-bot@automated.dev | Fake bot identity |
| Commit Author | build-system@noreply.dev | Alternate fake bot identity |
| Commit Date | September 17, 2001 | Hardcoded fake historical date on malicious commits |
| Base64 Prefix | Q0I9Imh0dHA6Ly8yMTYu | Start of encoded payload — GitHub code search returns 3,500+ infected YAML files |
Detection Queries
GitHub code search — find all infected workflow files across public repositories:
https://github.com/search?q=Q0I9Imh0dHA6Ly8yMTYu&type=code
This query searches for the base64 payload prefix and returns currently infected public YAML files. Run the same string grep locally across your own repositories:
grep -rn "Q0I9Imh0dHA6Ly8yMTYu" .github/workflows/
Find malicious commits by date (hardcoded fake date September 17, 2001):
git log --before="2002-01-01" -- .github/workflows/
GitHub Audit Log — workflow file modifications (gh CLI):
gh api /orgs/{org}/audit-log --paginate \
-F phrase=”action:workflows.created OR action:workflows.updated” \
| jq '.[] | select(.data.workflow_path | contains(".github/workflows"))'
Grep all workflow files in a repository for the malicious pattern:
grep -rn "base64 -d.*bash\|base64 -d | bash" .github/workflows/
Check for id-token: write permissions added to workflows:
grep -rn "id-token: write" .github/workflows/
Scanner References
- Phoenix Security — GitHub Actions workflow integrity scanner: monitors commits to .github/workflows/ for injection patterns and unexpected permission additions
- StepSecurity Harden-Runner: monitors runner process execution and network egress at job level — detects curl POST to unexpected external IPs
- Poutine (Boost Security): static analysis scanner for GitHub Actions workflow security misconfigurations including dangerous run: patterns
- GitHub Advanced Security — secret scanning does not detect this attack (no CVE, no package); workflow file monitoring via code scanning rules is required
Remediation Guidance
Immediate Actions
- Audit all
.github/workflows/files across every repository. Search forbase64 -d | bashin anyrun:step. Any match is a confirmed compromise. - For every repository where a workflow was modified: rotate all secrets accessible to runners — AWS access keys, GCP service account keys, SSH private keys, Docker Hub tokens, npm tokens, GitHub PATs stored as secrets.
- Revoke and reissue all OIDC trust configurations (AWS IAM OIDC providers, GCP Workload Identity Federation, Azure federated credentials) connected to affected repositories. Rotating repository secrets alone is not sufficient.
- Block outbound connections to
216.126.225.129at network egress for all self-hosted runners. - Review the GitHub audit log for the past 30 days for unexpected OAuth application grants, new PAT authorisations with push scope, and GitHub App installations with
contents: write.
Platform Responses
npm responded by invalidating granular access tokens with write access that bypass 2FA (npm statement, May 2026). This reduces account hijacking risk for npm registry tokens but does not address malicious workflow files already present in repositories or tokens exfiltrated before the revocation.
Structural Mitigations
- Enable required pull request reviews for all changes to
.github/workflows/using branch protection rules and CODEOWNERS with security team routing. - Audit every workflow for
id-token: write. This permission should only appear in workflows that explicitly document OIDC usage. - Scope repository secrets to specific environments and workflows using GitHub Environments with deployment protection rules.
- Replace long-lived IAM user credentials in CI runners with OIDC wherever possible — but treat OIDC configurations as requiring rotation after any repository-level compromise.
- For self-hosted runners: restrict IMDS access using IMDSv2 hop limit reduction (set hop limit to 1).
- Pin GitHub Actions to commit SHAs rather than branch or tag references.
Remediation Ownership Plan
| Owner | Action | Deadline |
|---|---|---|
| Platform / DevSecOps | Audit all workflow files for base64 -d | bash pattern | 24 hours |
| Platform / SecEng | Rotate all runner-accessible secrets in affected repositories | 24 hours |
| Cloud / IAM Team | Revoke and reissue OIDC trust configurations | 24 hours |
| NetSec | Block 216.126.225.129 at network perimeter | 24 hours |
| Platform | Enable required PR reviews for .github/workflows/ changes | 48 hours |
| AppSec | Audit all workflows for id-token: write permission | 48 hours |
| SecOps | Review GitHub audit log for suspicious access grants | 72 hours |
Phoenix Security Platform Recommendations
MEGALODON_CI has no CVE. Every traditional vulnerability scanner is blind to it. Detection requires controls at the workflow integrity and CI/CD posture layer — which is what Phoenix Security’s ASPM platform is built for.
Phoenix Security maps CI/CD workflow findings to the runtime assets they protect, identifies which runners hold credentials for live cloud workloads, and assigns remediation ownership to the teams responsible for each affected repository. A scattered incident becomes a tracked, owned backlog.
- Attack surface management: identify all repositories with active GitHub Actions workflows and surface those lacking workflow file protection controls
- Contextual deduplication: correlate runner compromise signals across repositories into a unified finding set, avoiding duplicate escalations to the same team
- Reachability analysis: identify which compromised runner secrets have reachable paths to production cloud workloads — prioritise rotation for runners with IAM roles attached to live environments
- Remediation campaigns: create a MEGALODON_CI campaign in Phoenix, assign workflow audit and secrets rotation tasks to owning teams, track verification status per repository
- Ownership attribution: map GitHub repositories to responsible engineering teams automatically — no manual triage of which team owns which repo workflow
- phxintel.security: Phoenix threat intelligence portal maintains the MEGALODON_CI IOC list including the C2 IP, device IDs, workflow signatures, and detection queries for SIEM integration
External References
| # | Source | Type | Date |
|---|---|---|---|
| 1 | GitHub commit — Tiledesk/tiledesk-server: acac5a9854650c4ae2883c4740bf87d34120c038 | Confirmed Compromise | May 2026 |
| 2 | GitHub commit — Davidf2004/Proyecto-GEOREFERENCIADOS: c93393ff847d4d49c348dc3b6581bdfb3a8e431f | Confirmed Compromise | May 2026 |
| 3 | Phoenix Security — MEGALODON_CI payload decode and IOC extraction (primary research) | Internal Research | May 2026 |
| 4 | MITRE ATT&CK — T1195.001 Supply Chain Compromise | Technique Reference | — |
| 5 | MITRE ATT&CK — T1528 Steal Application Access Token | Technique Reference | — |
| 6 | MITRE ATT&CK — T1552.001 Unsecured Credentials: Credentials In Files | Technique Reference | — |
| 7 | SafeDep — Megalodon: Mass GitHub repo backdooring CI workflows (original discovery) | External Research | May 2026 |
| 8 | OX Security — Megalodon: New CI/CD Malware Spreads Across GitHub, Infecting 5,000+ Repositories | External Research | May 2026 |
| 9 | npm statement — granular access tokens with write access bypassing 2FA invalidated | Platform Response | May 2026 |
| 10 | Phoenix Security phxintel.security — MEGALODON_CI threat intelligence feed | Phoenix Intel | May 2026 |