この記事の経緯
2026年2月24日、FutureVuls の定期リリースで trivy v0.69.1 のバイナリを GitHub Releases から取得しました。その4日後、trivy リポジトリが hackerbot-claw を名乗る自律型 AI エージェントによって侵害されました。バイナリの真正性検証を行い、改ざんがなかったことを確認してインシデント対応をクローズしています(検証レポート)。
インシデント対応の後、恒久対策を検討する中で気になったのが、今回の攻撃はワークフローの設定を事前に見直していれば予防できたのかという点です。攻撃後のインシデント分析は StepSecurity、Wiz、Datadog 等が公開しており、Datadog のブログでは GitHub Actions ワークフローの静的解析ツール zizmor が推奨されていました。
また、Boost Security の調査によると、CI/CD パイプラインスキャナー poutine は攻撃の3か月前(2025年11月)の時点で trivy の pull_request_target の脆弱性を指摘していました。ツールの警告に基づいてワークフローを修正していれば、少なくとも一部の攻撃は予防できた可能性があります。
ただし、これらは個別リポジトリに対する分析です。「標的となった7リポジトリのセキュリティ状態を横断的に比較し、攻撃ベクトルとの関係を検証する」という観点の分析は見当たりませんでした。そこで本記事では、StepSecurity の調査で標的として特定された7リポジトリの攻撃直前コミットに対して OpenSSF Scorecard CLI v5.4.0 をローカル実行し、Scorecard の警告と実際の攻撃ベクトルを突き合わせました。
hackerbot-claw 攻撃の概要
hackerbot-claw は2026年2月20日に作成された GitHub アカウントで、「claude-opus-4-5 搭載の自律型セキュリティリサーチエージェント」を自称していました(現在はアカウント削除済み)。プロフィールには 47,391 リポジトリをスキャン済みと表示されていましたが、この数字はプロフィール README 上の表示であり、第三者による検証はされていません。2月27日頃から3月2日にかけて GitHub Actions ワークフローの脆弱性を悪用し、StepSecurity の調査により少なくとも以下の7リポジトリが標的として特定されています。
| # | リポジトリ | 攻撃手法 | 結果 |
|---|---|---|---|
| 1 | aquasecurity/trivy | pull_request_target 悪用 |
PAT 窃取(後日リポジトリ乗っ取りに発展) |
| 2 | avelino/awesome-go | Go init() ポイズニング |
RCE + トークン窃取 |
| 3 | RustPython/RustPython | ブランチ名インジェクション | 部分的失敗 |
| 4 | project-akri/akri | スクリプトインジェクション | RCE 確認 |
| 5 | microsoft/ai-discovery-agent | ブランチ名インジェクション | RCE 推定 |
| 6 | DataDog/datadog-iac-scanner | ファイル名インジェクション | RCE 推定 |
| 7 | ambient-code/platform | AI プロンプトインジェクション | Claude がブロック |
攻撃手法はリポジトリごとに異なり、確認されているものは以下の6種類です。
| # | 手法 | 概要 | 対象リポジトリ |
|---|---|---|---|
| 1 | pull_request_target 悪用 |
信頼されないコードのチェックアウトにより PAT を窃取 | trivy |
| 2 | Go init() ポイズニング |
品質チェックスクリプトに init() 関数を注入し、main() より前に任意コード実行 |
awesome-go |
| 3 | スクリプトインジェクション | version.sh のシバン直後にペイロードを直接注入 |
akri |
| 4 | ブランチ名インジェクション | dev$({curl,...}) をブランチ名に埋め込み、echo コマンド経由で実行 |
RustPython, ai-discovery-agent |
| 5 | ファイル名インジェクション | Base64 エンコードしたコマンドをファイル名に隠蔽し、ワークフロー内で展開 | datadog-iac-scanner |
| 6 | AI プロンプトインジェクション | CLAUDE.md を書き換え、Claude Code に不正な操作を指示(Claude が拒否) | ambient-code |
hackerbot-claw 攻撃の調査方法
各リポジトリの攻撃直前コミットを特定し、チェックアウトした状態で Scorecard CLI をローカル実行しました。
# 例: trivy の場合
git clone https://github.com/aquasecurity/trivy.git
cd trivy
git checkout 2a140f1202fb2d5928348e6a1acc78ca5b7d9998
scorecard --local .
scorecard --local . --show-details --checks=Dangerous-Workflow,Token-Permissions
--localフラグを使用することで、過去の特定コミット時点のソースコードに対して Scorecard を実行できます。これにより、攻撃直前の状態を再現した検証が可能になります。
攻撃直前のコミット一覧は以下のとおりです。
| # | リポジトリ | 攻撃時刻 (UTC) | コミット日時 (UTC) | 攻撃直前コミット |
|---|---|---|---|---|
| 1 | trivy | 2/27 00:18 | 2/26 17:39 | 2a140f1202fb |
| 2 | awesome-go | 2/28 00:57 | 2/27 10:05 | f74f1806836e |
| 3 | RustPython | 3/2 05:57 | 3/2 04:13 | b1cddc4e0ca5 |
| 4 | akri | 2/28 | 2/6 | 4fe2f18328d3 |
| 5 | ai-discovery-agent | 2/27 | 12/4 (2025) | 6887fb5e75ca |
| 6 | datadog-iac-scanner | 2/27 05:26 | 2/25 15:45 | 000917415036 |
| 7 | ambient-code | 2/28 05:26 | 2/28 05:04 | 406ee34e482c |
Scorecard 結果一覧
7リポジトリの攻撃直前における Scorecard 結果です。攻撃に関連するチェック項目を抜粋しています。
| リポジトリ | 総合 | Dangerous-Workflow | Token-Permissions | Pinned-Dependencies | Vulnerabilities |
|---|---|---|---|---|---|
| trivy | 4.6/10 | 0/10 | 0/10 | 7/10 | 0/10 (305件検出) |
| awesome-go | 2.8/10 | 0/10 | 0/10 | 3/10 | 8/10 (2件検出) |
| RustPython | 1.8/10 | 0/10 | 0/10 | 1/10 | 0/10 (39件検出) |
| akri | 4.4/10 | 10/10 | 0/10 | 0/10 | 0/10 (31件検出) |
| ai-discovery-agent | 7.0/10 | 10/10 | 0/10 | 10/10 | 0/10 (44件検出) |
| datadog-iac-scanner | 2.8/10 | 10/10 | 0/10 | 0/10 | 0/10 (16件検出) |
| ambient-code | 3.1/10 | 0/10 | 0/10 | 0/10 | 0/10 (79件検出) |
各チェック項目の意味は以下のとおりです。
- Dangerous-Workflow —
pull_request_targetトリガーでの untrusted code checkout や、外部入力を直接埋め込む script injection など、CI ワークフロー上の危険なパターンを検出します。スコアが低いほど、攻撃者が PR 経由で任意コードを実行できるリスクが高くなります。 - Token-Permissions — GitHub Actions ワークフローでトークンの権限が最小化されているかを評価します。write-all 等のまま運用していると、トークン窃取時の被害範囲が広がります。
- Pinned-Dependencies — GitHub Actions やコンテナイメージなどの依存をタグではなくハッシュで固定(pin)しているかを評価します。タグは上書き可能なため、pin されていないとサプライチェーン攻撃のリスクがあります。
- Vulnerabilities — OSV(Open Source Vulnerabilities)データベースを参照し、リポジトリの依存関係に既知の脆弱性がないかを検出します。括弧内の件数は検出された脆弱性の数を示します。
結果から2つのパターンが読み取れます。
- Token-Permissions が全7リポジトリで 0/10
- Dangerous-Workflow は 0/10(4件)と 10/10(3件)に二分
以下、この2つのパターンについて分析します。
Scorecard の警告と攻撃ベクトルの一致 — Dangerous-Workflow 0/10 の3件
Dangerous-Workflow 0/10 だったリポジトリのうち3件について、Scorecard の警告内容と実際の攻撃ベクトルを突き合わせました。
trivy
Scorecard の警告:
Warn: untrusted code checkout 'refs/pull/$/merge':
.github/workflows/apidiff.yaml:59
Scorecard が検出した untrusted code checkout とは、いわゆる pwn request パターンです。通常の pull_request トリガーはフォークからの PR に対してリポジトリの secrets を渡しません。しかし pull_request_target トリガーはベースブランチのコンテキストで実行されるため secrets にアクセスできます。ここで PR のコードを明示的にチェックアウトすると、外部の攻撃者が送ったコードが secrets のある環境で実行されます。
trivy の apidiff.yaml は pull_request_target トリガーで PR のコードをチェックアウトしており、この構成に該当します。hackerbot-claw による攻撃では pull_request_target ワークフロー経由で PAT が窃取されたと想定されており、Scorecard の警告内容と攻撃経路が整合しています。
awesome-go
Scorecard の警告:
Warn: untrusted code checkout '$':
.github/workflows/pr-quality-check.yaml:40
awesome-go の pr-quality-check.yaml も pwn request 構成でした。攻撃者はこのワークフローを利用し、PR に Go の init() 関数を含むコードを送りました。Go の init() は main() より先に、パッケージの読み込み時点で自動実行されます。品質チェックスクリプトが PR のコードを読み込んだ瞬間に init() 内の任意コードが動作し、トークンが窃取されました。Scorecard が警告していたワークフローと、攻撃に使用されたワークフローが一致しています。
RustPython
Scorecard の警告(3件):
Warn: script injection with untrusted input ' github.event.pull_request.head.ref ':
.github/workflows/pr-auto-commit.yaml:96
Warn: untrusted code checkout '$':
.github/workflows/lib-deps-check.yaml:23
Warn: untrusted code checkout '$':
.github/workflows/pr-auto-commit.yaml:23
Scorecard が検出した script injection とは、ワークフロー内で $(PR 作成者のブランチ名)をシェルスクリプトに直接展開している脆弱性を指します。$ 式はシェル実行前にテンプレート展開されるため、ブランチ名にシェルメタ文字やコマンドを含めれば任意コード実行が成立します。
StepSecurity の分析によれば、攻撃者はこの脆弱性を突き、ブランチ名に Base64 エンコードしたコマンドを埋め込む手法(Branch Name Injection with Base64 Payload)を使用しました。Base64 エンコードは、ワークフローログ上でペイロードを難読化する目的と考えられます。
検出内容と攻撃手法の対応を整理すると、以下の関係になります。
- script injection — ワークフローに存在する脆弱性の種類(Scorecard が検出)
- Branch Name Injection — その脆弱性を突く攻撃手法(StepSecurity が分析)
- Base64 Payload — 検出回避のためのエンコーディング手段
Scorecard の警告は、この攻撃が成立する前提条件——head.ref のシェルへの直接展開——を事前に捉えていたことになります。3件に共通して、Scorecard は攻撃前の時点で、実際の攻撃ベクトルと整合する警告を出力しています。
Scorecard の検出範囲外 — Dangerous-Workflow 10/10 の3件
Dangerous-Workflow 10/10 と判定されていた3リポジトリが、いずれも攻撃を受けました。
akri(CNCF プロジェクト)
10 / 10 | Dangerous-Workflow | no dangerous workflow patterns detected
Scorecard は危険なパターンなしと判定しています。しかし実際の攻撃では、issue-comment トリガー経由で version.sh にペイロードが注入され、RCE が成功しました。Scorecard の Dangerous-Workflow チェックは pull_request_target での untrusted checkout と $ 式の script injection を主な検出対象としており、issue-comment トリガー経由の攻撃は対象外です。
ai-discovery-agent(Microsoft)
10 / 10 | Dangerous-Workflow | no dangerous workflow patterns detected
総合スコア 7.0/10 は7リポジトリ中で最高でした。攻撃者はブランチ名にシェルが解釈可能なコマンド文字列を埋め込み、ワークフロー内の echo コマンドにブランチ名がエスケープなしで渡されるパターンを悪用しました。このパターンは Scorecard の検出対象に含まれていません。スコアの高さが必ずしも安全性を保証するわけではないことが分かります。
datadog-iac-scanner
10 / 10 | Dangerous-Workflow | no dangerous workflow patterns detected
攻撃者はファイル名に Base64 エンコードしたコマンドを埋め込み、ワークフローがファイル名を bash に補間する箇所を悪用しました。ファイル名を bash コンテキストに補間するパターンは Scorecard の検出対象外です。
補足: ambient-code
攻撃者は AI プロンプトインジェクション(CLAUDE.md の書き換え)を使用しましたが、Claude(Sonnet 4.6)が攻撃を認識しブロックしたと説明されています。
Token-Permissions — 全7リポジトリで 0/10
全7リポジトリで Token-Permissions が 0/10 でした。
GitHub Actions のワークフロートークン(GITHUB_TOKEN)は、2023年2月以前に作成されたリポジトリではデフォルトで contents: write を含む広い権限(permissive)を持ちます。2023年2月以降に新規作成されたリポジトリでは read-only がデフォルトになりましたが、既存リポジトリの設定は変更されていません。今回の標的7リポジトリのうち4つ(trivy, awesome-go, RustPython, akri)は2023年2月以前から存在しており、デフォルトが permissive です。
残り3つ(ai-discovery-agent, datadog-iac-scanner, ambient-code)は2023年2月以降に作成されたリポジトリですが、Scorecard の詳細出力を確認すると、いずれも 0/10 でした。トップレベルで permissions が未定義のワークフローや、リリース・CI 結果の書き込みなどの目的で write 権限が個別に設定されたワークフローが存在していたためです。
Token-Permissions の過剰権限は今回の攻撃の直接原因ではありませんが、攻撃成功時の被害範囲を拡大させる要因になりえます。トークンの権限が read のみであれば、リポジトリの改ざんやリリースの差し替えは困難になります。
対策として、ワークフローのトップレベルに permissions: read-all を設定し、ジョブごとに必要な権限のみを付与する方法があります。
permissions: read-all
jobs:
build:
permissions:
contents: read
考察 — Scorecard で防げたか
結果を整理します。
trivy、awesome-go、RustPython の3件は、Scorecard の Dangerous-Workflow 警告が攻撃ベクトルと一致していました。これらの警告に基づいてワークフローを修正していれば、攻撃を防げた可能性があります。
akri、ai-discovery-agent、datadog-iac-scanner、ambient-code の4件は、Scorecard の検出範囲外の手法が使用されていました。
Scorecard の Dangerous-Workflow チェックの検出範囲を整理します。
検出対象:
pull_request_targetトリガーでの untrusted code checkout$式による script injection(PR タイトル、PR ボディ、ブランチ名の一部パターン)
Scorecard の公式ドキュメントでは、それぞれ以下のように説明されています。
Untrusted Code Checkout: This is the misuse of potentially dangerous triggers. This checks if a
pull_request_targetorworkflow_runworkflow trigger was used in conjunction with an explicit pull request checkout. Workflows triggered withpull_request_target/workflow_runhave write permission to the target repository and access to target repository secrets.Script Injection with Untrusted Context Variables: This pattern detects whether a workflow's inline script may execute untrusted input from attackers. This occurs when an attacker adds malicious commands and scripts to a context. When a workflow runs, these strings may be interpreted as code that is executed on the runner.
検出対象外:
- issue-comment トリガー経由のスクリプトインジェクション
- ファイル名を bash コンテキストに補間するパターン
echoコマンドへのブランチ名の未エスケープ補間- AI プロンプトインジェクション
Scorecard は3/7 で攻撃ベクトルと整合する警告を事前に出力しています。一方で4/7 は検出範囲外であり、Scorecard のスコアのみでリポジトリの安全性を判断することは難しいと考えられます。
また、冒頭で触れたとおり、GitHub Actions ワークフローのセキュリティをチェックするツールは Scorecard 以外にも zizmor や poutine が存在します。
対策TODO
本調査の結果を踏まえ、GitHub Actions を利用するリポジトリで確認すべき項目をまとめます。
- [ ] Scorecard を実行し、Dangerous-Workflow の警告がないか確認する
- [ ] 全ワークフローのトップレベルに
permissions: read-allを設定し、ジョブごとに必要最小限の権限のみを付与する - [ ] zizmor や poutine など、Scorecard と同様に GitHub Actions ワークフローのセキュリティをチェックするツールでもスキャンする。単一のツールに依存せず、複数ツールを併用することで検出範囲の補完となる可能性がある
また、本調査の対象外ですが、GitHub Actions の参照を SHA ハッシュでピン留めすること(actions/checkout@v6 → actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2)も GitHub Actions のセキュリティ対策として広く推奨されています。Organization の Actions Policy で SHA ピン留めを必須化することも可能です。
再現手順
本記事のすべてのデータは以下の手順で再現できます。
Scorecard CLI のインストール
go install github.com/ossf/scorecard/v5@v5.4.0
各リポジトリの検証コマンド
# 1. trivy
git clone https://github.com/aquasecurity/trivy.git
cd trivy && git checkout 2a140f1202fb2d5928348e6a1acc78ca5b7d9998
scorecard --local .
scorecard --local . --show-details --checks=Dangerous-Workflow,Token-Permissions
cd ..
# 2. awesome-go
git clone https://github.com/avelino/awesome-go.git
cd awesome-go && git checkout f74f1806836e156a6d105740055c27577653e4b0
scorecard --local .
scorecard --local . --show-details --checks=Dangerous-Workflow,Token-Permissions
cd ..
# 3. RustPython
git clone https://github.com/RustPython/RustPython.git
cd RustPython && git checkout b1cddc4e0ca59f14e9c7d2535beb97c1710ef231
scorecard --local .
scorecard --local . --show-details --checks=Dangerous-Workflow,Token-Permissions
cd ..
# 4. akri
git clone https://github.com/project-akri/akri.git
cd akri && git checkout 4fe2f18328d3ef8655796cf7ae8266ffe6e42687
scorecard --local .
scorecard --local . --show-details --checks=Dangerous-Workflow,Token-Permissions
cd ..
# 5. ai-discovery-agent (2026-04-02 にアーカイブ済み)
git clone https://github.com/microsoft/ai-discovery-agent.git
cd ai-discovery-agent && git checkout 6887fb5e75cab39686156395b043f854f948ac23
scorecard --local .
scorecard --local . --show-details --checks=Dangerous-Workflow,Token-Permissions
cd ..
# 6. datadog-iac-scanner
git clone https://github.com/DataDog/datadog-iac-scanner.git
cd datadog-iac-scanner && git checkout 0009174150367fc99e7b34cd27d5045a66d99e8a
scorecard --local .
scorecard --local . --show-details --checks=Dangerous-Workflow,Token-Permissions
cd ..
# 7. ambient-code/platform
git clone https://github.com/ambient-code/platform.git
cd platform && git checkout 406ee34e482c4a0db4dc4c2e4013b4e1ef531c5f
scorecard --local .
scorecard --local . --show-details --checks=Dangerous-Workflow,Token-Permissions
cd ..
ai-discovery-agent は2026年4月1日(UTC)にアーカイブされていますが、git cloneは可能です。
参考記事
- FutureVuls: trivy サプライチェーン攻撃 バイナリ安全性検証レポート
- StepSecurity: hackerbot-claw GitHub Actions exploitation
- Orca Security: HackerBot-Claw deep dive
- Datadog: Stopping hackerbot-claw with BewAIre
- Palo Alto Networks: trivy supply chain attack breakdown
- Boost Security: MegaGame10418 — The user behind hackerbot-claw
- OpenSSF Scorecard
- OpenSSF Scorecard Checks Documentation
- zizmor: Static analysis for GitHub Actions
- poutine: CI/CD pipeline security scanner