在 confluent-kafka 中为 HashiCorp Vault KMS 禁用 TLS 证书验证
严重性: 高,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 之间具备网络中间人位置的攻击者可以:
X-Vault-Tokenrole_idsecret_id这可能危及由 Vault 支持的 KMS 工作流所保护数据的机密性和完整性。
confluent-kafka 是 Confluent 官方的 Apache Kafka 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 身份验证时,客户端将以下内容发送到:
/v1/auth/approle/login
的内容包括:
role_id
secret_id
因此,成功的中间人攻击可以捕获这两个 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://
方案。
可能的示例包括:
一旦具备必要的中间人位置,就不需要应用程序级权限或受害者交互。
poc_confluent_kafka.py 针对本地解包的 confluent-kafka 2.14.2 wheel 演示了该问题。
PoC 使用:
HcVaultKmsClient 实现。概念验证包含五种模式。
安装 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 客户端构造。
使用两个终端。
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
至
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 — 高
AV:N — 网络
易受攻击的 Vault 通信通过网络连接进行。
AC:H — 高攻击复杂度
攻击者必须获得网络中间人位置或以其他方式重定向 Vault 连接。
这是一个重要的前提条件,也是该漏洞被评为高而非严重的原因。
PR:N — 无需权限
攻击者不需要在受影响应用程序内拥有权限。
UI:N — 无需用户交互
攻击者获得必要的网络位置后,无需用户交互。
S:U — 范围不变
影响仍处于受影响应用程序及其 Vault 交互的安全权限范围内。
C:H — 高机密性影响
Vault 令牌或 AppRole 凭据可能暴露给攻击者。
I:H — 高完整性影响
攻击者可以冒充 Vault 并返回伪造的 Vault/KMS 响应。
A:N — 无可用性影响
未演示直接的可用性影响。
2.8.0 至 2.14.22.15.0硬编码的 verify=False 从 HCVault 集成引入之初一直存在到版本 2.14.2。
该安全行为已在 2.15.0 中得到纠正。
YYYY-MM-DD — 报告给 Confluent。2.15.0。由 Rahul Karne 发现并报告。
confluent-kafka-python
https://github.com/confluentinc/confluent-kafka-python
PyPI 上的 confluent-kafka
https://pypi.org/project/confluent-kafka/
HashiCorp hvac Python 客户端
https://hvac.readthedocs.io/
HashiCorp Vault AppRole 身份验证
https://developer.hashicorp.com/vault/api-docs/auth/approle
CWE-295 — 证书验证不当
https://cwe.mitre.org/data/definitions/295.html
Python TLS / 证书验证文档
https://docs.python.org/3/library/ssl.html#ssl-security
本仓库记录了一项协调披露的安全发现,并提供了一个无害、自包含的概念验证。
PoC 完全针对使用虚拟凭据的本地模拟 Vault 服务器运行。
它不与真实的 HashiCorp Vault、Kafka、Schema Registry、生产基础设施或真实凭据交互。
这些材料仅供防御性安全研究和教育目的使用。
媒体咨询:[email protected]。完整 PoC(攻击者服务器、遍历归档、受害者应用程序)及更多技术细节可应要求提供。
| 模式 | 描述 |
|---|
cert | 为本地模拟 Vault 生成自签名证书和密钥。 |
server | 在 https://localhost:8443 上启动模拟 HTTPS Vault 并显示接收到的请求。 |
control | 使用 verify=True 的安全对照;应拒绝自签名证书并报 CERTIFICATE_VERIFY_FAILED。 |
token | 加载易受攻击的 HcVaultKmsClient 并演示其接受不受信任的证书。 |
approle | 演练易受攻击的 AppRole 身份验证路径,并演示 role_id 和 secret_id 的暴露。 |