Skip to content
KitploitKITPLOIT
أدواتعمليات الاستغلالالمدونة
Log in
إرسال
أدواتعمليات الاستغلالالمدونة
إرسال

أدوات الاختراق واختبار الاختراق والأمن السيبراني لترسانتك الأمنية!

Kitploit هو دليل لأدوات الاختراق والأمن السيبراني واختبار الاختراق. اكتشف آخر تحديثات المشاريع للعثور على الثغرات وتحليل الأنظمة وأتمتة الاختبارات وتعزيز أمنك.

الخلاصاتاتصالالخصوصية© 2026 Kitploit

دليل الأدوات

الفئات

عرض جميع الفئات
Loading categories
CVE-2026-94386 — مُعيد إنتاج قابل للتشغيل بـ Spring Boot وQuarkus لـ CVE-2026-94386، يُوضّح إعادة استخدام رمز OAuth عبر النطاقات في ذاكرة التخزين المؤقت الثابتة للرموز في Apache Camel camel-oauth. | Kitploit
أدوات/GitHubGitHub/oscerd/cve-2026-94386
أدوات دفاعيةتحليل الثغرات الأمنيةأمن الويبالمصادقةالتعلم والتعليم
GitHuboscerd/cve-2026-94386

CVE-2026-94386

مُعيد إنتاج قابل للتشغيل بـ Spring Boot وQuarkus لـ CVE-2026-94386، يُوضّح إعادة استخدام رمز OAuth عبر النطاقات في ذاكرة التخزين المؤقت الثابتة للرموز في Apache Camel camel-oauth.

عرض المستودع
منذ يوم واحدلم تتم المراجعة بعد

الأكثر شعبية

عرض الكل →

اكتشف الأدوات الأكثر استخدامًا من قبل مجتمعنا.

استكشف جميع الأدوات

تصفح مجموعتنا من الأدوات

عرض جميع الأدوات →
مشاركة

CVE-2026-94386 — camel-oauth: إعادة استخدام الرموز عبر النطاقات عبر ذاكرة تخزين مؤقت للرموز عامة على مستوى JVM بمفتاح غير كافٍ

مُعيد إنتاج عملي قابل للتشغيل لإثبات المفهوم لثغرة Apache Camel حيث كان OAuthClientCredentialsTokenResolver يحتفظ برموز بيانات اعتماد العميل التي حصل عليها في ذاكرة تخزين مؤقت ثابتة (static) مشتركة بين كل نسخة resolver وكل CamelContext في الـ JVM، وكان يفتح تلك الذاكرة المؤقتة على نقطة نهاية الرمز ومُعرّف العميل فقط — على الرغم من أن طلب الرمز يحمل أيضًا سر العميل و النطاق المطلوب.

// affected
record TokenCacheKey(String tokenEndpoint, String clientId) { }
وقت التشغيلالدليلالمكدس
Camel Spring Bootcamel-spring-boot/Spring Boot 3.5.13 + camel-oauth 4.22.1
Camel Quarkuscamel-quarkus/Camel Quarkus 3.39.0 (Quarkus 3.39.0, Camel 4.22.0)

ما الذي يوضحه

ملفان شخصيان (profile) يتشاركان نقطة نهاية رمز (token endpoint) ومعرّف عميل (client ID) واحدًا لكنهما يطلبان نطاقات (scopes) مختلفة، أو يصادقان بـ أسرار عميل (client secrets) مختلفة، مرتبطةً بمدخل ذاكرة تخزين مؤقت (cache entry) واحد. الملف الشخصي الذي حلّ أولًا هو من ملأه؛ ثم سُلِّم الرمز الآخر، دون إجراء أي طلب رمز وفقًا لتكوينه الخاص، طالما بقي الرمز صالحًا.

تخزين الرموز المؤقت مفعّل افتراضيًا، وتوجيه عدة ملفات شخصية إلى عميل واحد لدى مزوّد الهوية هو استخدام عادي لدعم الملفات الشخصية وليس اشتراكًا في إعداد غير آمن.

cd camel-spring-boot          # or: cd camel-quarkus
mvn clean package
docker compose up -d --build
until curl -sf http://localhost:8080/exploit/ready >/dev/null; do sleep 1; done
curl -s http://localhost:8080/exploit/attack
docker compose down

الإخراج على بناء متأثر (متطابق على كلا زمني التشغيل):

1) Profile 'invoices' resolves first
     token handed to it: TOKEN-FOR[scope=invoice.read;secret=...aaaa]
     token requests the IdP has received: 1

2) Profile 'admin' resolves next, through a DIFFERENT resolver instance
     token handed to it: TOKEN-FOR[scope=invoice.read;secret=...aaaa]
     token requests the IdP has received: 1  (unchanged - no request was made under its own config)
     it was handed the token issued for the OTHER profile's scope: true

3) Profile 'partner' - same endpoint and clientId, DIFFERENT client secret (...-zzzz)
     token handed to it: TOKEN-FOR[scope=invoice.read;secret=...aaaa]
     it was served the token obtained with the other secret, without ever
     authenticating with its own: true

4) CONTROL - profile 'admin' again with cache-tokens=false
     token handed to it: TOKEN-FOR[scope=admin.write;secret=...aaaa]
     it got a token for its own scope: true

Everything the IdP was actually asked for:
  - client_id=camel-integration-client scope=invoice.read;secret=...aaaa
  - client_id=camel-integration-client scope=admin.write;secret=...aaaa

>>> PROVEN: ...

قيمة الرمز تسمّي النطاق والسرّ الذي صدر من أجله، لذا يمكنك رؤية أي ملف تعريف جاء منه كل رمز فعليًا. سجل الطلبات في النهاية هو الدليل القاطع: مع تفعيل التخزين المؤقت، لم يُسأل مزوّد الهوية عن رمز ملف تعريف admin إطلاقًا — يظهر فقط طلب ملف التعريف الأول وطلب الضابط.

يستخدم الفحص 2 نسخة محلّل ثانية عن قصد: فالتخزين المؤقت static، لذا تتشاركه نسخة منفصلة — وCamelContext منفصل.

من المتأثر

يحصل المحلّل على الرموز نيابةً عن المكوّنات التي تصادق على استدعاءاتها الصادرة باستخدام ملف تعريف OAuth مسمّى — camel-openai وcamel-langchain4j-agent وcamel-huggingface وcamel-docling وcamel-a2a وcamel-spring-ai-chat ومكوّنات IBM watsonx — وعن التطبيقات التي تستدعي واجهة SPI ‏OAuthClientAuthenticationFactory مباشرةً.

يتطلب الوصول إلى المشكلة عملية نشر تعرّف أكثر من ملف تعريف يتشارك نقطة نهاية رمز ومعرّف عميل مع اختلافهما في النطاق أو سرّ العميل.

نموذج التهديد

تُضبط ملفات التعريف بواسطة عملية النشر، وهي موثوقة، لذا لا يصل أي إدخال غير موثوق إلى التخزين المؤقت. الطرف المستفيد هو الخدمة التي تتلقى رمزًا لم يكن من المفترض أن تتلقاه، والتي يمكنها، إن كانت معادية أو مخترقة، إعادة استخدام ذلك الرمز ضمن نطاقه. النتيجة هي طلب صادر يحمل رمزًا صادرًا لنطاق ملف تعريف آخر — سلطة أوسع مما كان ملف التعريف المستدعي مهيأً له، أو خدمة لم يصدر الرمز من أجلها. ومع مزوّدي الهوية الذين يستنبطون جمهور الرمز من النطاق المطلوب، قد يعني نطاق مختلف رمزًا لخدمة مختلفة تمامًا.

كيف تم ربطه

لا مزوّد هوية ولا شبكة. يستضيف التطبيق بديلًا لنقطة نهاية الرمز الخاصة بالمزوّد يخدم منحة بيانات اعتماد العميل، ويصدر رمزًا تسمّي قيمته النطاق وسرّ العميل الذي صدر من أجله، ويسجّل كل طلب. يعمل OAuthClientCredentialsTokenResolver الحقيقي والتخزين المؤقت الثابت الحقيقي.

يقرأ البديل بيانات اعتماد العميل من ترويسة تفويض HTTP Basic، لا من معاملات النموذج، لأن camel-oauth يرسلها بهذه الطريقة.

ملخص الثغرة

الخاصيةالقيمة
المكوّنcamel-oauth (OAuthClientCredentialsTokenResolver)
CWECWE-524 (Use of Cache Containing Sensitive Information)
الخطورةمتوسطة
ناقل الهجومملفّا تعريف OAuth أو أكثر يتشاركان نقطة نهاية رمز ومعرّف عميل مع اختلافهما في النطاق أو سرّ العميل
الأثرطلب صادر يحمل رمزًا صادرًا لنطاق ملف تعريف آخر أو تم الحصول عليه بسرّ ملف تعريف آخر
الإصدارات المتأثرةمن 4.19.0 قبل 4.22.2
الإصدارات المُصلحة4.22.2، 4.23.0
JIRACAMEL-24872
الفضلAndrea Cosentino من Apache Software Foundation

الإشعار الأمني: https://camel.apache.org/security/CVE-2026-94386.html

الإصلاح

يحتفظ مفتاح التخزين المؤقت الآن بكل مدخلات طلب الرمز: نقطة نهاية الرمز، ومعرّف العميل، وبصمة SHA-256 لسرّ العميل — حتى لا يُحتفظ بالسرّ الخام في التخزين المؤقت الثابت — والنطاق المطلوب. يُحتسب النطاق الغائب أو الفارغ أو المكوّن من مسافات فقط كقيمة واحدة، لأن كلًّا منها يستبعد معامل scope من الطلب؛ وأي نطاق آخر يُطابَق بدقة. ملفات التعريف المتفقة على الأربعة جميعًا لا تزال تتشارك رمزًا عبر نسخ المحلّل، بينما تحصل ملفات التعريف المختلفة في بيانات الاعتماد أو النطاق على رموز منفصلة.

أُصلح على main في apache/camel#26681 (5e896b2d)، ونُقل إلى camel-4.22.x في #27779 (b2d9957b).

التحقق من بناء مُصلح

اضبط camel.version على 4.22.2 وشغّله مرة أخرى. تم التحقق مقابل 4.22.1 → 4.22.2:

2) Profile 'admin' resolves next, through a DIFFERENT resolver instance
     token handed to it: TOKEN-FOR[scope=admin.write;secret=...aaaa]
     token requests the IdP has received: 2
     it was handed the token issued for the OTHER profile's scope: false

3) Profile 'partner' ... token handed to it: TOKEN-FOR[scope=invoice.read;secret=...zzzz]
     it was served the token obtained with the other secret ...: false

>>> NOT reproduced: each profile got a token for its own scope and secret.

تصل الآن جميع طلبات الرموز الأربعة إلى مزوّد الهوية، كل منها وفق إعداداته الخاصة.

التخفيف دون الترقية

عطّل تخزين الرموز مؤقتًا في كل ملف تعريف OAuth يتشارك نقطة نهاية رمز ومعرّف عميل مع ملف تعريف آخر — camel.oauth.NAME.cache-tokens=false لملف تعريف مسمّى، وcamel.oauth.cache-tokens=false للملف الافتراضي — وذلك على حساب إرسال طلب رمز عند كل عملية حلّ (يُظهر الفحص 4 أن هذا يعمل). بدلاً من ذلك، سجّل عميل مزوّد هوية منفصلًا لكل ملف تعريف يحتاج إلى نطاق أو سرّ عميل مختلف، بحيث لا يتشارك أي ملفَي تعريف من هذا القبيل معرّف عميل واحدًا.

إخلاء المسؤولية

نُشر هذا المستودع لأغراض تعليمية ودفاعية: لمساعدة مستخدمي Apache Camel على فهم الثغرة، والتحقق مما إذا كانوا متأثرين بها، وتأكيد أن الترقية تعالجها. لا تستخدم هذه المواد ضد أنظمة لا تملكها أو لا تديرها.

تنزيل الأداة