
تعطيل التحقق من شهادة TLS لـ HashiCorp Vault KMS في confluent-kafka
الخطورة: عالية، 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
يقوم عميل HashiCorp Vault KMS في confluent-kafka بتثبيت verify=False بشكل صلب عند إنشاء hvac.Client الخاص به، مما يعطّل التحقق من شهادة TLS لاتصالات Vault عبر HTTPS التي تتم من خلال قواعد تشفير حقول Schema Registry.
يقع الكود الثغرة في:
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يمكن أن يؤدي هذا إلى اختراق السرية والسلامة للبيانات المحمية بواسطة سير عمل KMS المدعوم بـ Vault.
confluent-kafka هو عميل Confluent Python الرسمي لـ Apache Kafka.
تؤثر الثغرة تحديدًا على عمليات النشر التي تستخدم:
Schema Registry encryption rules
↓
HCVault KMS integration
↓
hcvault:// key URI
لذلك فإن الفئة المتأثرة أضيق من جميع مستخدمي confluent-kafka.
ومع ذلك، فإن الوظيفة المتأثرة حساسة أمنيًا لأن عمليات النشر هذه تعتمد على HashiCorp Vault لإدارة المفاتيح التشفيرية والتشفير على مستوى الحقل.
يقوم HcVaultKmsClient.__init__() بتحليل URI مفتاح hcvault://، ويحدد عنوان URL الأساسي لـ Vault، وينشئ 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 في النهاية على حزمة TLS الخاصة بـ Python requests.
تعيين:
verify=False
يوجّه العميل إلى عدم التحقق من شهادة TLS الخاصة بالخادم البعيد.
ونتيجة لذلك، يمكن قبول الشهادات التي كان سيتم رفضها عادةً، بما في ذلك الشهادات التي تكون:
يؤثر هذا على كلا مساري المصادقة المدعومين.
عند استخدام مصادقة الرمز، يتم إرسال رمز Vault عبر:
X-Vault-Token
ترويسة HTTP.
إذا نجح المهاجم في انتحال هوية نقطة نهاية 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.يستخدم التطبيق قواعد تشفير Schema Registry مع تكامل HCVault KMS.
يستخدم مفتاح KMS المُكوَّن:
hcvault://
المخطط.
تشمل الأمثلة المحتملة:
لا يُطلب أي امتيازات على مستوى التطبيق أو تفاعل من الضحية بمجرد وجود موقع MITM اللازم.
poc_confluent_kafka.py يوضح المشكلة مقابل حزمة confluent-kafka 2.14.2 غير المضغوطة محليًا.
يستخدم PoC:
HcVaultKmsClient الحقيقي الثغرة.يحتوي إثبات المفهوم على خمسة أوضاع.
| الوضع | الوصف |
|---|---|
cert | ينشئ شهادة ومفتاحًا موقّعين ذاتيًا لـ Vault الوهمي المحلي. |
server | يبدأ Vault الوهمي عبر HTTPS على https://localhost:8443 ويعرض الطلبات المستلمة. |
control | تحكم آمن باستخدام verify=True؛ يجب أن يرفض الشهادة الموقعة ذاتيًا مع CERTIFICATE_VERIFY_FAILED. |
token | يحمّل HcVaultKmsClient الثغرة ويوضح أنه يقبل الشهادة غير الموثوقة. |
approle | يمارس مسار مصادقة AppRole الثغرة ويوضح تعرض role_id وsecret_id. |
ثبّت تبعيات PoC:
pip install hvac cryptography
ضع الحزمة الثغرة غير المضغوطة بجانب PoC:
confluent_kafka-2.14.2-cp310-cp310-win_amd64/
└── confluent_kafka/
└── schema_registry/
└── ...
يستورد PoC HcVaultKmsClient مباشرةً من حزمة 2.14.2 غير المضغوطة.
يقوم بإنشاء بدائل للتبعيات غير ذات الصلة مثل tink، مما يسمح باختبار إنشاء عميل Vault الثغرة دون الحاجة إلى بيئة Kafka أو KMS كاملة.
استخدم طرفيتين.
python poc_confluent_kafka.py server
يستمع Vault الوهمي عبر HTTPS على:
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"}