flawopen.com/Teardowns/cve-2024-7646-ingress-nginx-annotation-code-injection
CVE-2024-7646:Ingress-NGINX の検証回避
復帰文字による検証回避で Ingress 作成者がコマンドを注入し、ingress-nginx の認証情報を取得できました。1.11.2/1.10.4 で修正済み。プロジェクトは終了。
許可語が含まれるかだけを調べ、値全体を検証しない門番を想像してください。復帰文字によって、次のシステムが残りのテキストを別の方法で解釈することがあります。この問題では、annotation が部分一致検査を通過し、生成された NGINX 設定に書き込まれました。修正では値全体を検証し、復帰文字を安全に処理します。
主要な概念と専門用語
Ingress オブジェクト- ホストまたはパスから Service へのルーティングを定義する Kubernetes API リソースです。クラスタ管理者でない利用者に作成権限が付与されることがあります。
annotation 検証回避- 許可された部分文字列を見つけるだけの validator を通過し、値全体が許可された選択肢と一致するかは検証されませんでした。
復帰文字 (`\r`)- 形式によって改行として使われる制御文字です。検証時と設定生成時で解釈が違うと、行の開始位置が変わる場合があります。
コントローラーの ServiceAccount- ingress-nginx コントローラーが使う Kubernetes の ID です。上流通知によれば、既定権限でクラスタ内すべての Secrets にアクセスできる場合があります。
フレームワーク対応
- このガイドで説明する弱点の CWE 参照: CWE-20
根本原因の分析 (Root Cause)
CVE-2024-7646 は ingress-nginx の annotation 検証回避であり、任意の Lua snippet を自由に使える問題ではありません。auth-tls-verify-client の validator は開始・終了アンカーのない Go 正規表現を使っていたため、MatchString は許可値を部分文字列として含む長い値も受け入れる可能性がありました。annotation 内の復帰文字は、生成された NGINX 設定を整える段階で異なる解釈を受ける可能性がありました。上流修正では値全体の一致を要求し、cleanConf で単独の復帰文字を安全に扱います。Kubernetes のセキュリティ通知によると、Ingress オブジェクトの作成権限を持つ主体は検証を回避してコマンドを注入し、コントローラーの認証情報を取得できます。既定設定では、その認証情報がクラスタ内の全 Secrets にアクセスできる場合があります。これは高深刻度(CVSS 8.8)の認証済み Kubernetes API 経路であり、任意のネットワーククライアントからの匿名要求ではありません。プロジェクトは2026年3月に終了したため、歴史的修正版への更新は緊急の封じ込めにすぎません。運用環境は保守中のコントローラーまたは Gateway API 実装へ移行してください。
ステップ・バイ・ステップの攻撃フロー
ユーザーに Ingress 作成権限がある
攻撃者には Kubernetes API で Ingress オブジェクトを作成する権限が必要です。アプリケーションチームにこの権限を委譲するマルチテナントクラスタで特に問題になります。
annotation が部分一致検査を通る
脆弱な auth-tls-verify-client 正規表現にアンカーがありませんでした。そのため Go MatchString は、完全一致ではなく許可値を含む長い値を受け入れる可能性がありました。
復帰文字が設定境界の解釈を変える
annotation は生成された NGINX 設定に組み込まれます。パッチ群は、値全体の検証と設定整理時の単独復帰文字の処理を修正します。
コントローラーの ID が露出する
Kubernetes 通知によると、コマンド注入でコントローラーの認証情報を取得できます。既定では ServiceAccount がすべての Secrets を読めますが、影響は RBAC 設定によります。
ソースコード比較:脆弱 vs 堅牢化
このコード断片は CVE-2024-7646 の上流修正に基づきます。PR #11719 は auth-tls-verify-client の許可値にアンカーを追加し、PR #11721 は cleanConf で単独の復帰文字を処理します。1.10 系にも PR #11718 と #11722 の対応変更が入りました。関係のない関数周辺コードは省略しています。
// internal/ingress/annotations/authtls/main.go(修正前)
authVerifyClientRegex = regexp.MustCompile(`on|off|optional|optional_no_ca`)
// internal/ingress/controller/template/template.go(修正前)
switch c {
case ' ', '\t':
needOutput = lineStarted
case '\n':
needOutput = !(!lineStarted && emptyLineWritten)
nextLineStarted = false
}
// internal/ingress/annotations/authtls/main.go(修正後)
authVerifyClientRegex = regexp.MustCompile(`^(on|off|optional|optional_no_ca)$`)
// internal/ingress/controller/template/template.go(修正後)
switch c {
case '\r':
rest := in.Bytes()
if len(rest) > 0 && rest[0] != '\n' {
c = ' '
needOutput = lineStarted
}
case '\n':
needOutput = !(!lineStarted && emptyLineWritten)
nextLineStarted = false
}
エンジニアリング&システム堅牢化チェックリスト
- ✓特にマルチテナントクラスタでは、Ingress オブジェクトを作成・編集できる Kubernetes RBAC 権限を制限します。この権限が脆弱な経路への入口でした。
- ✓歴史的な封じ込めとして、1.11 系は ingress-nginx 1.11.2 以降、1.10 系は 1.10.4 以降へ更新します。ベンダーのイメージと chart の正確な版を確認してください。
- ✓上流通知に従い、
nginx.ingress.kubernetes.io/auth-tls-verify-clientを含む Ingress annotation に復帰文字 (\r) がないか Kubernetes 監査ログを確認します。 - ✓
allow-snippet-annotations: "false"をこの CVE の修正とみなさないでください。影響したのは annotation 検証と設定行処理であり、snippet 機能だけではありません。 - ✓Ingress NGINX は2026年3月に終了しました。保守中のコントローラーまたは Gateway API 実装への移行を計画してください。歴史的修正以降のセキュリティ更新はありません。