
confluent-kafka における HashiCorp Vault KMS の TLS 証明書検証の無効化
深刻度: High、CVSS 3.1 7.4
ベクター (v3.1): CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:N
影響を受けるバージョン: confluent-kafka >= 2.8.0, <= 2.14.2
修正バージョン: 2.15.0
CWE: CWE-295 (不適切な証明書検証)
コンポーネント: confluent_kafka/schema_registry/rules/encryption/hcvault/hcvault_client.py
報告者: Rahul Karne
CNA: VulnCheck
confluent-kafka の HashiCorp Vault KMS クライアントは、hvac.Client を構築する際に verify=False をハードコードしており、Schema Registry のフィールド暗号化ルールを通じて行われる Vault HTTPS 接続の TLS 証明書検証を無効化しています。
脆弱なコードは以下にあります:
confluent_kafka/schema_registry/rules/encryption/hcvault/hcvault_client.py
影響を受けるクライアントは次のように初期化されます:
self._client = hvac.Client(
url=vault_url,
token=token,
namespace=ns,
verify=False
)
verify=False が無条件であるため、クライアントは信頼できない TLS 証明書 (自己署名証明書や攻撃者が制御する証明書を含む) を受け入れます。
アプリケーションの Vault トラフィックを傍受またはリダイレクトできるネットワーク上の攻撃者は、Vault サーバーになりすまし、Vault 認証情報を窃取し、偽造された Vault/KMS レスポンスを返すことができます。
影響を受ける HCVault 統合は、Vault トークン、名前空間、AppRole 認証情報の設定を公開していますが、影響を受けるバージョンでは、証明書検証を復元するためのサポートされた CA バンドル設定や同等のメカニズムが提供されていません。
アプリケーションと HashiCorp Vault の間にネットワーク中間者 (MITM) の位置を占める攻撃者は、以下を行うことができます:
X-Vault-Tokenrole_idsecret_idこれにより、Vault をバックエンドとする KMS ワークフローで保護されたデータの機密性と完全性が損なわれる可能性があります。
confluent-kafka は Apache Kafka 向けの公式 Confluent Python クライアントです。
この脆弱性は、以下を使用するデプロイメントに特に関係します:
Schema Registry encryption rules
↓
HCVault KMS integration
↓
hcvault:// key URI
したがって、影響を受ける対象はすべての confluent-kafka ユーザーよりも狭い範囲に限られます。
しかし、影響を受ける機能は、これらのデプロイメントが暗号鍵管理とフィールドレベルの暗号化を HashiCorp Vault に依存しているため、セキュリティ上重要です。
HcVaultKmsClient.__init__() は hcvault:// キー URI を解析し、Vault のベース URL を決定して hvac.Client を作成します。
2.14.2 を含む影響を受けるバージョンでは、関連するコードは次のとおりです:
self._client = hvac.Client(
url=vault_url,
token=token,
namespace=ns,
verify=False
)
if role_id and secret_id and self._client is not None:
self._client.auth.approle.login(
role_id=role_id,
secret_id=secret_id
)
hvac ライブラリは最終的に Python の requests TLS スタックに依存しています。
次の設定は:
verify=False
クライアントに対してリモートサーバーの TLS 証明書を検証しないよう指示します。
その結果、通常は拒否される証明書が受け入れられる可能性があります。これには以下の証明書が含まれます:
これはサポートされている両方の認証パスに影響します。
トークン認証が使用される場合、Vault トークンは以下の HTTP ヘッダーを通じて送信されます:
X-Vault-Token
攻撃者が Vault エンドポイントのなりすましに成功した場合、攻撃者が制御するサーバーがこのトークンを受信できます。
AppRole 認証が使用される場合、クライアントは以下を送信します:
role_id
secret_id
送信先:
/v1/auth/approle/login
したがって、MITM が成功すると、両方の AppRole 認証情報を窃取できます。
影響を受ける HCVault ドライバーは、以下を含む設定を読み取ります:
token.id
namespace
approle.role.id
approle.secret.id
および関連する VAULT_* 環境変数。
しかし、影響を受けるバージョンでは、運用者が以下を行えるようにする設定が公開されていません:
その結果、影響を受ける統合を使用するアプリケーションは、通常のパッケージ設定を通じて TLS 検証を復元できません。
このパッケージは、安全なデフォルトに依存するのではなく、TLS サーバー証明書検証を明示的に無効化しています。
脆弱な構築は実質的に次のとおりです:
hvac.Client(..., verify=False)
次のようなものではなく:
hvac.Client(..., verify=True)
または単に:
hvac.Client(...)
ここでは検証がデフォルトで有効になっています。
証明書検証を無効化すると、TLS 接続からサーバー認証が削除されます。
接続は暗号化されたままですが、クライアントは正当な Vault サーバーと通信しているかどうかを判断する信頼できるメカニズムを持ちません。
これにより、ネットワーク中間者攻撃に必要な条件が生じます。
悪用の成功には以下が必要です:
アプリケーションが影響を受けるバージョンの confluent-kafka を使用している:
2.8.0 から 2.14.2。アプリケーションが HCVault KMS 統合 を伴う Schema Registry 暗号化ルールを使用している。
設定された KMS キーが以下のスキームを使用している:
hcvault://
考えられる例としては以下が含まれます:
必要な MITM の位置が存在すれば、アプリケーションレベルの権限や被害者の操作は不要です。
poc_confluent_kafka.py は、ローカルに展開された confluent-kafka 2.14.2 wheel に対してこの問題を実証します。
PoC は以下を使用します:
HcVaultKmsClient 実装。概念実証には 5 つのモードがあります。
| モード | 説明 |
|---|---|
cert | ローカルのモック Vault 用の自己署名証明書と鍵を生成する。 |
server | https://localhost:8443 でモック HTTPS Vault を起動し、受信したリクエストを表示する。 |
control | verify=True を使用した安全な制御。自己署名証明書を CERTIFICATE_VERIFY_FAILED で拒否するはずである。 |
token | 脆弱な HcVaultKmsClient をロードし、信頼できない証明書を受け入れることを実証する。 |
approle | 脆弱な AppRole 認証パスを実行し、role_id と secret_id の露出を実証する。 |
PoC の依存関係をインストールします:
pip install hvac cryptography
展開した脆弱な wheel を PoC の隣に配置します:
confluent_kafka-2.14.2-cp310-cp310-win_amd64/
└── confluent_kafka/
└── schema_registry/
└── ...
PoC は、展開された 2.14.2 パッケージから HcVaultKmsClient を直接インポートします。
tink などの無関係な依存関係をスタブ化し、完全な Kafka や KMS 環境を必要とせずに脆弱な Vault クライアントの構築をテストできるようにします。
2 つのターミナルを使用します。
python poc_confluent_kafka.py server
モック HTTPS Vault は以下でリッスンします:
https://localhost:8443
自己署名証明書を使用します。
まず、適切な証明書検証が自己署名サーバーを拒否することを実証します:
python poc_confluent_kafka.py control
期待される結果:
EXPECTED TLS failure: CERTIFICATE_VERIFY_FAILED
-> verify=True correctly rejected the self-signed cert
実行:
python poc_confluent_kafka.py token
脆弱な HcVaultKmsClient は、サーバーが信頼できない証明書を提示しているにもかかわらず接続します。
モックサーバーは Vault トークンを観察できます:
GET /v1/auth/token/lookup-self
X-Vault-Token: CNA-DEMO-VAULT-TOKEN
X-Vault-Namespace: cna-demo-namespace
実行:
python poc_confluent_kafka.py approle
モック Vault は以下を受信します:
POST /v1/auth/approle/login
{"role_id": "CNA-DEMO-ROLE-ID", "secret_id": "CNA-DEMO-SECRET-ID"}
安全な control モードと脆弱な token / approle モードの対比は、この動作がテスト環境によるものではなく、ハードコードされた以下に起因することを実証します:
verify=False
基本的な安全な修正は、hvac に証明書検証を実行させることです:
hvac.Client(
url=vault_url,
token=token,
namespace=ns
)
TLS 検証はデフォルトで有効になっているため、明示的に無効化する必要はありません。
堅牢な実装は以下を行うべきです:
デフォルトで TLS 証明書検証を有効にする。
設定可能な CA バンドルをサポートする。例えば:
ssl.ca.location
VAULT_CACERT
相互 TLS を使用する環境向けにクライアント証明書をサポートする。
空または偽の設定値が証明書検証を暗黙的に無効化するのを防ぐ。
自己署名証明書およびその他の信頼できない証明書がデフォルトで拒否されることを確認する回帰テストを追加する。
この脆弱性は以下で修正されています:
confluent-kafka 2.15.0
影響を受けるバージョンは以下です:
2.8.0
through
2.14.2
2.15.0 では、Vault クライアントの動作が変更され、TLS 検証がデフォルトで有効になりました。
更新された実装では、以下を含む TLS 関連の設定も導入されています:
ssl.ca.location
VAULT_CACERT
ssl.certificate.location
ssl.key.location
これにより、プライベート PKI インフラストラクチャを使用するデプロイメントは、証明書検証を無効化することなく、信頼された CA およびクライアント証明書の設定を提供できます。
この脆弱性のスコアは:
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:N
CVSS 3.1 スコア: 7.4 — High
AV:N — Network
脆弱な Vault 通信はネットワーク接続を介して行われます。
AC:H — High Attack Complexity
攻撃者はネットワーク MITM の位置を取得するか、Vault 接続をリダイレクトする必要があります。
これは重大な前提条件であり、この脆弱性が Critical ではなく High と評価される理由です。
PR:N — No Privileges Required
攻撃者は影響を受けるアプリケーション内の権限を必要としません。
UI:N — No User Interaction
攻撃者が必要なネットワーク上の位置を取得した後、ユーザーの操作は不要です。
S:U — Scope Unchanged
影響は、影響を受けるアプリケーションとその Vault 相互作用のセキュリティ権限内にとどまります。
C:H — High Confidentiality Impact
Vault トークンまたは AppRole 認証情報が攻撃者に露出する可能性があります。
I:H — High Integrity Impact