Mika Ayenson, PhD

CI/CDパイプラインの悪用:誰も注目していない問題

GitHub Actions、GitLab CI、Azure DevOpsパイプラインにおけるCI/CDの不正利用を検出するために、シグナル抽出とLLM推論を利用した、オープンソースでそのまま導入可能なCIテンプレートをどのように構築したか。

前文

2025 と2026年には、業界全体で一つのパターンが展開されるのを目にしました。攻撃者は本番サーバーへの直接攻撃をやめ、サーバーにデプロイする自動化システムを標的にし始めた。開発者の認証情報が漏洩し、ワークフローファイルが改ざんされると、CI/CD環境内のあらゆる機密情報が攻撃者が制御するエンドポイントにストリーミングされてしまう。私たちは、主要なオープンソースプロジェクトフォーチュン 500 企業重要インフラツールに関連するインシデント全体でこれが展開されるのを目撃しました。

攻撃の手順は一見単純だが、実はそうではない。

開発者認証情報の盗難 → ワークフローファイルの改ざん → CIシークレットの収集 → クラウドおよび本番環境への横方向の移動

本日、CI/CDパイプラインへの疑わしい変更を検出するために正規表現ベースのシグナル抽出とLLM分析を使用する、すぐに使えるCIテンプレートであるcicd-abuse-detectorをオープンソース化します。これはGitHub Actions、GitLab CI、Azure DevOps全体で動作し、公開されているセキュリティ研究で文書化されている実際の攻撃手法に基づいて設計されています。

重要なポイント

  • CI/CD環境は、単一のワークフローが侵害されるだけで、クラウド認証情報、パッケージレジストリトークン、コード署名キー、デプロイキー、およびOIDCトークンを同時に流出させる可能性があるため、非常に価値の高い標的です。
  • このツールは、差分データから50種類以上の正規表現とメタデータシグナルを抽出し、それらを完全な差分データとともにClaudeに渡して、構造化された脅威分析を行います。Pythonは不要、bashとClaude Code CLI以外に依存関係もありません。
  • 検出パターンは、 Nord StreamGato-Xなどの攻撃ツールキット、およびArtiPACKEDHackerBot-Clawなどの実際のインシデントに対してテストされました。
  • このプロジェクトには、特定の事件をモデルにした悪意のある差分が 19 と良性の差分が4個、そしてすべてのシグナルを検証する自動テストスイートが同梱されています。

CI/CDパイプラインが最優先ターゲットとなる理由

GitHub ActionsやGitLab CIの設定を時間をかけて確認すると、これらのファイルにどれだけの信頼が集中しているかに気づくかもしれません。一般的なデプロイワークフローでは、AWS認証情報、npm公開トークン、Docker Hubパスワード、書き込み権限を持つGitHubトークンに同時にアクセスできます。攻撃対象はCVEを持つサーバーではなく、YAMLファイルである。

大規模な認証情報収集

盗まれた開発者認証情報を持つ攻撃者がワークフローを改変し、CI環境で利用可能な機密情報を外部に持ち出す。9月に行われたGhostActionキャンペーン 2025 は、これを大規模に実証し、 817 リポジトリにわたる 327 GitHubユーザーを侵害しました。攻撃者のエンドポイントに認証情報をPOST送信するワークフローファイルが挿入されたことにより、3,325件の機密情報が盗まれた。

Shai-Hulud npmワームはさらに進んだ。この自己増殖型攻撃は、gh auth token を介して GitHub の個人アクセストークンを収集し、 TruffleHogを実行して秘密裏に偵察を行い、侵害されたトークンを使用して、同じ開発者が所有する他のパッケージに悪意のあるコードを密かに注入しました。最初の波だけでも、4万6000件以上の悪意のあるパッケージが公開された。

特権トリガーの悪用

pull_request_targetトリガーは、GitHub Actionsの中で最も危険な機能の一つです。通常のpull_requestトリガーとは異なり、シークレットへのアクセス権を持つベースリポジトリのコンテキストでワークフローを実行しますが、信頼されていないフォークからのコードも実行できます。Orcaの「プルリクエストの悪夢」に関する研究は、Google、Microsoft、NVIDIAが管理するリポジトリに対してこのことを実証した。

2026年2月、 HackerBot-Clawと呼ばれる自動化されたキャンペーンが、まさにこの設定ミスを探すために、公開リポジトリを体系的にスキャンした。この攻撃では、毒されたGo init() 、ブランチ名コマンドの注入、ファイル名に基づく注入、直接スクリプトの注入、Claudeベースのコードレビュー担当者に対するAIプロンプトの注入など、5つの異なる攻撃手法が使用されました。最も深刻なケースでは、Aqua Security社のTrivyリポジトリが完全に侵害され、下流のサプライチェーン攻撃につながり、約7,000台のマシンにわたって33,000件の機密情報が漏洩した。既に報告されているように、このサプライチェーン攻撃は、最初に盗まれた後数週間経っても有効な、不正に改ざんされたトークンを利用して行われた。

分類体系の残りの部分

認証情報の窃盗やトリガーの悪用以外にも、この脅威モデルは、公開されている調査で一貫して見られる4つの追加カテゴリを網羅しています。

これらはそれぞれ 、 MITRE ATT&CKの 特定のテクニックに対応しています。T1552(安全でない認証情報)、 T1195 (サプライチェーン侵害)、 T1070.006 (タイムスタンプ)、 T1059 (コマンドおよびスクリプトインタープリタ)。

検出器の仕組み

私たちは、Python、カスタムランタイム、複雑な依存関係を必要とせずにテンプレートが動作することを望んでいました。すべてはデフォルトのubuntu-latestランナー上の標準シェルユーティリティで実行され、唯一インストールされているツールはnpm経由のClaude Code CLIで、認証、再試行、モデルルーティングを処理します。

ステージ1:フィルタリングと差分

プルリクエストが開かれたとき(または保護されたブランチにプッシュが行われたとき)、ワークフローはCI/CDに関連する3つの階層のパスにわたって変更されたファイルを識別します。第1層では、ワークフロー定義、パイプライン構成、MakefileなどのコアとなるCIファイルが対象となります。2つ目は、Dockerfile、パッケージマニフェスト、ロックファイル、署名スクリプトやデプロイスクリプトといった、ビルドおよびリリース成果物に関するものです。第3層では、.vscode/tasks.jsonや.devcontainerなどの開発者環境設定を取得します。ファイル。

各ファイルは個別に差分比較され、文字数は10,000文字に制限されます。これをグローバルではなくファイルごとに行うのは、結合された差分に単一のキャップがあると、回避策となるためです。攻撃者は、悪意のあるワークフローの変更に、大きな無害なDockerfile編集を付け加えることで、エクスプロイトを文字数制限を超えて実行させることができます。

ステージ2:信号抽出

LLMが何かを検出する前に、50以上の正規表現パターンが各差分をスキャンして、既知の危険なパターンを検出します。これらのシグナルは助言的なものです。彼らは分析を制限することはないが、LLM(法執行管理責任者)に事前選別済みの脅威概要を提供する。いくつか例を挙げると:

信号パターン捕獲するもの
secrets_context${{.*secrets.ワークフローにおける直接的な秘密補間
pull_request_targetpull_request_targetPRコードに秘密を付与する危険なトリガー
checkout_refref:.*github.event.pull_request.head.(sha|ref)信頼できないPRコードが特権コンテキストでチェックアウトされました
double_base64base64.*|.*base64ログマスキングを回避するための二重エンコード(Nord Streamの手法)
ld_preloadLD_PRELOAD環境変数注入による任意のコード実行
vscode_auto_taskrunOn.*folderOpenフォルダを開いたときに実行されるVS Codeタスク(Contagious Interview)

シグナルリストは、 Nord StreamGato-Xなどの実際の攻撃ツールに基づいており、特定の事件をモデルにした 19 の悪意のある差分サンプルに対してテストされています。

この検出器は、GitHub Actions、GitLab CI、Azure DevOpsのいずれにおいても全く同じように動作します。各プラットフォームで発生した検知事象は以下のとおりです。

ステージ3:LLM分析

シグナルサマリー、完全な差分、作成者プロファイル、およびコミットメタデータはバンドルされ、Claude Code CLI を介して Claude に送信されます。分析プロンプトは、モデルをいくつかの領域にわたって順に処理します。

  1. 差分の理解とファイルごとのリスク評価
  2. 文脈を考慮した信号解釈(信号だけでは判断できない)
  3. 過去のコミットに関する時間的分析
  4. アカウント開設時期、投稿履歴、組織メンバーシップを用いた著者の信頼性評価
  5. 60以上のエントリを含む信号組み合わせテーブルに対する重症度較正
  6. 誤検出(例:既知のツールをダウンロードするためのcURLはデータ漏洩ではない)
  7. 具体的で実行可能な推奨事項(「慎重に確認する」ではなく、「actions/setup-node@main を特定の SHA に固定する」など)

出力は、深刻度、信頼度、理由、証拠、推奨事項を含む構造化されたJSON形式の判定であり、すべてJSONスキーマに対して検証されます。

ステージ4:警告とゲート

判定の重大度に基づいて、ワークフローはステップの概要を投稿し、課題を作成し、Slack通知を送信し、重大度が設定されたしきい値に達した場合は、オプションでプルリクエストのチェックを失敗させます。

SlackやGitHub Issuesのアラート機能は、即時通知の問題を解決しますが、履歴を照会することはできません。検出器が生成するすべての判定(例:(良性、疑わしい、または悪意のある)ログは、オプションで構造化ドキュメントとしてlogs-cicd.abuse-defaultに送信されます。データストリーム。このワークフローは、判定結果とCI/CDメタデータ(プラットフォーム、リポジトリ、アクター、イベントタイプ、実行URL)を、サポートされている3つのプラットフォームすべてにまたがる単一のインデックスに格納して送信します。

ここで、プラットフォーム間の相関関係が実用的になる。同じアクターからのGitHub ActionsアラートとGitLab CIアラートは同じデータストリームに格納され、単一のES|QLステートメントでクエリ可能です。

FROM logs-cicd.abuse-* 
WHERE verdict.verdict IN ("malicious", "suspicious") AND @timestamp > NOW() - 7 days 
EVAL platform = cicd.platform, repo = cicd.repository, actor = cicd.actor, severity = verdict.severity
KEEP @timestamp, platform, repo, actor, severity
SORT @timestamp DESC

スキーマには cicd.platform が含まれます。cicd.リポジトリ、cicd.actor と完全な評決オブジェクト (評決、重大度、信頼度、概要、理由、証拠) により、検出ルールを簡単に構築できます。1時間以内に複数のリポジトリを攻撃する組織的なキャンペーン、複数のプラットフォームで報告された常習犯、またはインシデント対応ページが必要となる重大な発見の急増は、相関関係がある可能性があります。

実際の攻撃に対する検証

検出範囲を検証するために、攻撃ツールの実際のソースコード、公開されている研究論文、および公開されている事後分析結果と、我々の検出パターンを比較しました。

Nord Stream: 逐語的なペイロードの一致

Nord Streamは、Synacktivが開発したオープンソースのCI/CDシークレット抽出ツールで、GitHub、GitLab、Azure DevOpsをサポートしています。YAMLジェネレーターのソースコード( nordstream/yaml/github.py )を取得し、その出力テンプレートをサンプル差分と比較しました。

  • GitHub のペイロード テンプレートはenv -0 | awk -v RS='0' '/^secret_/ {print $0}' | base64 -w0 | base64 -w0を使用します。私たちのnord-stream-pipeline-exfil.diffにはこの行がそのまま含まれており、私たちのdouble_base64env_null_dumpenv_secret_grep信号はすべて発火します。
  • OIDC Azureテンプレートは、 azure/login@v1id-token: write権限を付与し、続いてazアカウントget-access-token | base64 -w0 | base64 -w0を使用します。私たちのdiffはこの正確な流れを捉え、 cloud_auth_actionid_token_writeをトリガーします。
  • Azure DevOps パイプライン技術 (SPN 認証情報の漏洩のためのaddSpnToEnvironment 、セキュアファイルの盗難のためのDownloadSecureFilessh.js変更による SSH タスク ソースのパッチ適用) はすべてnord-stream-azure-devops.diffに存在し、プラットフォーム固有のシグナルによって検出されます。

ArtiPACKED: アーティファクトの競合状態

Palo Alto Unit 42 のArtiPACKED研究では、チェックアウト ディレクトリ全体をアーティファクトとしてアップロードすると、 GITHUB_TOKENを含む.git/configファイルが漏洩することが示されました。v4アーティファクトAPIでは実行途中のダウンロードが可能になっているため、攻撃者はジョブが完了する前にトークンを抽出して使用することができます。

私たちのartifact-token-leak.diffは、 upload-artifactpath: . (ワークスペース全体)を使用して、このパターンを正確にモデル化しています。upload_artifactシグナルがそれを捕捉し、LLMはアップロード範囲に.gitディレクトリが含まれているかどうかを評価します。

GITHUB_ENV の注入: LD_PRELOAD による RCE の悪用

Legit Security による Google Firebase と Apache に関する調査では、信頼できない入力を$GITHUB_ENVに書き込むことで、攻撃者がLD_PRELOADNODE_OPTIONSのような任意の環境変数を設定でき、特権ワークフローでコード実行が可能になることが示されました。

我々のgithub-env-injection.diffは、悪意のある共有オブジェクトを指すLD_PRELOAD 、必要なインジェクションを含むNODE_OPTIONSGITHUB_PATH操作を含む3つの異なるペイロードを使用してこの技術を再現します。github_env_writeld_preloadgithub_path_write信号はすべて想定どおりにトリガーされます。

伝染するインタビュー:IDE構成を初期アクセスとして使用

北朝鮮によるものとされる「伝染性面接」キャンペーンは、偽の就職面接を通じて開発者を標的にし、フォルダを開くと自動的に実行される.vscode/tasks.jsonのファイルを含むリポジトリを配布している。プレゼンテーションは非表示( reveal: neverecho: false )で、ペイロードはサイレント実行のためにcurl | nodeを使用します。

我々のide-config-poisoning.diff 、自動実行トリガー( runOn: folderOpen )、隠されたプレゼンテーション、 curl | nodeペイロード、 .vscodeディレクトリを隠すfiles.excludeエントリ、およびbase64エンコードされたURLとコード実行用のeval()を含むトロイの木馬化されたインストール後フックを含む、攻撃チェーン全体を捉えます。6つの信号が同時にこれを検知する。

防御のための推奨アクション

検出器の導入に加えて、我々が調査した攻撃パターンから直接導き出された、いくつかのセキュリティ強化策を以下に示します。

  • すべてのアクションをタグやブランチではなく、SHAに紐付けます。SHA で固定された参照は、 tj-actions (CVE-2025-30066) のような遡及的なタグ変更攻撃を防ぎます。
  • ジョブレベルの環境変数を使用するのではなく、個々のステップにシークレットの範囲を限定する。各ステップは、実際に必要な秘密情報のみにアクセスできるべきである。
  • 攻撃対象領域を減らすため、可能な限り短命で一時的なトークンを使用する。
  • どうしても必要な場合を除き、 pull_request_targetは避けてください。どうしても使用する必要がある場合は、同じワークフロー内でプルリクエストのヘッダーコードをチェックアウトしないでください。シークレットとPRコンテキストの両方が必要な操作には、別のworkflow_run-triggered workflow使用してください。
  • デフォルトのトークン権限は広範すぎるため、すべてのワークフローに明示的な権限を設定してください。ワークフローレベルでpermissions: {}を設定し、ジョブごとに特定の権限を追加します。
  • アクション/チェックアウトのデフォルトの動作では、 GITHUB_TOKEN.gitディレクトリに保持されるため、チェックアウト時にpersist-credentials: false有効にしてください。成果物をアップロードすると、このトークンもそれに付随します。

まとめ

CI/CDパイプラインは、サプライチェーンの侵害に対する主要な攻撃対象となっている。現代のソフトウェア配信を可能にしている自動化技術は、攻撃者が認証情報を盗み出し、パッケージを汚染し、クラウドインフラストラクチャに侵入するために悪用する手段でもある。従来のコードレビューでは、これらのパターンをうまく検出できません。なぜなら、それらは微妙で、プラットフォーム固有のものであり、正当なDevOpsの変更のように見えるように設計されているからです。

正規表現に基づくシグナル抽出とLLM推論を組み合わせることで、これらのパターンを本番環境に到達する前のプルリクエスト段階で明らかにすることができます。このリポジトリには、完全な脅威モデル、テストスイート、および詳細を調べたり、独自の環境に合わせて調整したりするためのサンプル差分が含まれています。

まずは、 cicd-abuse-detectorリポジトリを参照して、セットアップ手順、完全な脅威モデル、および差分の例を確認してください。私たちは常に、新しい攻撃パターンや検出方法に関するアイデアに興味を持っています。コミュニティSlackでチャットしたり、ディスカッションフォーラムで質問したりしてください。

MITRE ATT&CK を通じた CI/CD の悪用

私たちはMITRE ATT&CKフレームワークを使用して、攻撃者がCI/CDパイプラインに対して使用する戦術、技術、および手順をマッピングします。

戦術(Tactics)

戦術CI/CDの関連性
認証情報アクセス(TA0006)CI環境から秘密情報を抽出する
実行(TA0002)パイプラインランナーでコマンドを実行する
持続性(TA0003)スケジュールされたトリガー、cronベースのワークフロー
防御回避(TA0005)コミットタイムスタンプの操作、ログマスキングの回避
初期アクセス(TA0001)開発者認証情報の漏洩、PAT(個人アクセストークン)のフィッシング
横方向の動き(TA0008)収集したクラウド認証情報を使用して方向転換する

手法

テクニックCI/CDアプリケーション
T1552: 安全でない認証情報CI環境変数、アーティファクト、ランナーメモリに隠された秘密
T1195.002: ソフトウェアサプライチェーンの侵害有害なアクション、依存関係、およびロックファイル
T1059: コマンドおよびスクリプト インタープリタcurl
T1070.006: タイムストンプレビューを回避するためにコミット日を遡及する
T1098: アカウント操作write-all、id-tokenによる権限昇格: write
T1078: 有効なアカウント盗まれた開発者PATを使用してワークフローが変更された

参照資料

上記の研究を通じて、以下のことが参照されました。

Elastic Security Labsについて

Elastic Security Labsは、Elasticセキュリティの脅威インテリジェンス部門であり、脅威の状況にポジティブな変化をもたらすことに専念しています。 Elastic Security Labsは、新たな脅威に関する一般向けの調査を提供し、戦略的、運用的、戦術的な敵対者の目標を分析し、その調査をElasticセキュリティの組み込み検知および対応機能と統合します。

TwitterでElastic Security Labsをフォロー @elasticseclabswww.elastic.co/security-labs/ の調査結果をご覧ください。

この記事を共有する