
HashiCorp Vault KMS에서 confluent-kafka의 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 사이에 네트워크 중간자(man-in-the-middle) 위치를 확보한 공격자는 다음을 수행할 수 있습니다:
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 구현.개념 증명은 다섯 가지 모드를 포함합니다.
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
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 — 높음
AV:N — 네트워크
취약한 Vault 통신은 네트워크 연결을 통해 발생합니다.
AC:H — 높은 공격 복잡도
공격자는 네트워크 MITM 위치를 확보하거나 Vault 연결을 리다이렉트해야 합니다.
이는 중요한 전제 조건이며, 이 취약점이 심각(Critical)이 아닌 높음(High)으로 평가되는 이유입니다.
PR:N — 권한 불필요
공격자는 영향받는 애플리케이션 내에서 권한이 필요하지 않습니다.
UI:N — 사용자 상호작용 불필요
공격자가 필요한 네트워크 위치를 확보한 후에는 사용자 상호작용이 필요하지 않습니다.
S:U — 범위 변경 없음
영향은 영향받는 애플리케이션과 그 Vault 상호작용의 보안 권한 내에 머뭅니다.
C:H — 높은 기밀성 영향
Vault 토큰 또는 AppRole 자격 증명이 공격자에게 노출될 수 있습니다.
I:H — 높은 무결성 영향
공격자는 Vault를 사칭하고 위조된 Vault/KMS 응답을 반환할 수 있습니다.
A:N — 가용성 영향 없음
직접적인 가용성 영향은 입증되지 않았습니다.
2.8.0부터 2.14.2까지2.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
이 저장소는 조정된 공개(coordinated-disclosure) 보안 발견 사항을 문서화하고 무해하며 자체 포함된 개념 증명을 제공합니다.
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의 노출을 시연합니다. |