
أداة إثبات مفهوم قابلة للتشغيل لإعادة إنتاج CVE-2026-78163 في Apache Camel camel-docling، تُظهر SSRF والكشف عن الملفات المحلية عبر إدخال String body غير المُتحقَّق منه، مع ضابط بناء مُصحَّح.
مُعيد إنتاج عملي قابل للتشغيل (proof-of-concept) لثغرة Apache Camel حيث كان DoclingProducer يقرر معنى جسم رسالة
من نوع String عبر فحص بادئته:
http:// أو https:// كان يُسلَّم إلى Docling كـ عنوان URL بعيد لجَلبه (SSRF)، و/ (أو يحتوي على شرطة مائلة عكسية) كان يُقرأ من نظام الملفات المحلي (كشف الملفات).كان الوضع يُختار ضمنيًا، دون أي خيار في نقطة النهاية لتثبيت تفسير واحد، وعلى عكس مساحة أسماء ترويسات Camel —
لا يُرشَّح جسم الرسالة أبدًا بواسطة HeaderFilterStrategy. لذا فإن مسارًا يعني
"حوِّل أي نص يصل في الجسم" أصبح بصمت جالبًا لموارد بعيدة أو قارئًا لملفات محلية
كلما بدأ النص الذي يتحكم فيه المهاجم بأحد تلك البادئات.
| بيئة التشغيل | الدليل | الحزمة | ما يُظهره |
|---|---|---|---|
| Camel Spring Boot | camel-spring-boot/ | Spring Boot 3.5.13 + camel-docling 4.22.0 (متأثر؛ مُصلَح في 4.22.1) | SSRF و كشف الملفات، إضافةً إلى ضابط البناء المُصلَح |
| Camel Quarkus | camel-quarkus/ | Quarkus 3.29.0 + camel-quarkus-docling 3.29.0 (Camel 4.15.0، متأثر) | كشف الملفات فقط (انظر الملاحظة) |
تغطية الإصدارات. وُجد مصرف كشف الملفات المحلي منذ إدخال camel-docling في 4.15.0؛ وأُضيف مصرف عنوان URL البعيد في 4.16.0 مع دعم docling-serve. أحدث إصدار من Camel Quarkus (3.29.0) يتضمن Camel 4.15.0، لذا تُظهر وحدته كشف الملفات فقط. يأتي الإصلاح في Camel 4.18.5 / 4.22.1 / 4.23.0؛ تشغّل وحدة Spring Boot كلاً من البناء المتأثر (4.22.0) والبناء المُصلَح (4.22.1)، لذا تُظهر أيضًا السلوك المُرقَّع. لا يوجد إصدار منشور من Camel Quarkus يتضمن بعد نسخة Camel مُصلَحة.
لا يحتاج أي من مُعيدَي الإنتاج إلى تثبيت Docling حقيقي: أداة سطر أوامر docling مزيفة صغيرة (fake-docling/docling) تقوم مقام
الملف التنفيذي وتُظهر ما كان الملف الحقيقي سيفعله بالإدخال الذي يوفره المنتج — جلب عنوان URL، أو قراءة
ملف. وهي غير ضارة: فهي تكرر فقط ما طُلب منها معالجته وتُسجّل استدعاءها الخاص. جوهر هذه الثغرة (CVE) هو
أن جسمًا يوفره المهاجم يصل إلى تلك الوسيطة أصلًا، دون أي تفعيل صريح.
كما تشغّل تطبيق Spring Boot نقطة نهاية HTTP داخلية فقط على 127.0.0.1:9099 (المنفذ 8080 فقط هو المنشور،
لذا لا يستطيع عميل خارجي الوصول إلى 9099 مباشرةً) وملف سرّي محلي. لا يرسل المهاجم سوى نص:
http://127.0.0.1:9099/internal-secret ← استدعاء docling من جهة الخادم يجلب
نقطة النهاية الداخلية ويُعاد سرّها إلى المستدعي./tmp/cve-2026-78163-secret.txt ← يُقرأ الملف المحلي ويُعاد.على البناء المتأثر ينجح كلاهما؛ وعلى البناء المُصلَح يُرفض كلاهما برمي IllegalArgumentException
يذكر الخيار (allowUrlSource / allowFilePathSource) الذي سيكون مطلوبًا لتمكينهما، ولا يُستدعى docling
أبدًا.
cd camel-spring-boot
mvn clean package
docker compose up -d --build
curl -s http://localhost:8080/exploit/attack
docker compose down
الناتج المتوقع على بناء Spring Boot المتأثر:
[1] SSRF — sending body = http://127.0.0.1:9099/internal-secret
>>> PROVEN SSRF: the server-side docling invocation fetched the attacker-controlled internal URL.
>>> internal victim saw: [GET /internal-secret]
>>> content returned to the caller:
| INTERNAL-SECRET-DATA (only reachable from inside the deployment)
[2] File disclosure — sending body = /tmp/cve-2026-78163-secret.txt
>>> PROVEN file disclosure: the attacker-named local file was read and returned.
| TOP-SECRET-FILE-CONTENT (local file an attacker should not be able to read)
| الخاصية | القيمة |
|---|---|
| المكوّن | camel-docling (camel-docling-starter / camel-quarkus-docling) |
| CWE | CWE-918 (SSRF)، CWE-22 (Path Traversal)، CWE-200 (Information Exposure) |
| الخطورة | MEDIUM |
| ناقل الهجوم | يُمرَّر نص رسالة من نوع String إلى نقطة نهاية docling، حيث تحدّد بادئته مصرف جلب عنوان URL أو قراءة ملف؛ ولا يخضع النص لـ HeaderFilterStrategy |
| التأثير | جلب من جهة الخادم لعناوين URL يختارها المهاجم (خدمات داخلية) والكشف عن ملفات محلية |
| الإصدارات المتأثرة | من 4.15.0 قبل 4.18.5، ومن 4.19.0 قبل 4.22.1 (كشف الملفات منذ 4.15.0؛ مصرف URL منذ 4.16.0) |
| الإصدارات المُصلحة | 4.18.5، 4.22.1، 4.23.0 |
| JIRA | CAMEL-24422 |
| الفضل | Li Zhiyao (BUPT) |
الإشعار الأمني: https://camel.apache.org/security/CVE-2026-78163.html
يُعامَل نص من نوع String الآن على أنه المستند نفسه افتراضيًا. أصبح تفسيرا الموقع اختياريين عبر
خيارَي نقطة النهاية الجديدين allowUrlSource وallowFilePathSource (كلاهما افتراضيًا false)؛ وإلا يُرفض أي نص
يشبه عنوان URL أو مسارًا برفع IllegalArgumentException يذكر الخيار الذي من شأنه تمكينه. كما يقيّد خيار إضافي
inputBaseDirectory مسارات الإدخال المحلية بدليل مُهيّأ. أما النصوص المُصنّفة (File، byte[]،
InputStream) وترويسة CamelDoclingInputFilePath فتُصرّح بمعناها مسبقًا ولا تخضع للبوابة (لكنها تبقى
خاضعة لـ inputBaseDirectory).
لا تُمرّر نصوص الرسائل الواردة من مصادر خارجية إلى نقطة نهاية docling؛ مرّر المستند عبر نص مُصنّف
(File، byte[]، InputStream) أو عبر ترويسة CamelDoclingInputFilePath بحيث لا يخضع النص أبدًا لتفسير
البادئة.
يُنشر هذا المستودع لأغراض تعليمية ودفاعية: لمساعدة مستخدمي Apache Camel على فهم
الثغرة الأمنية، والتحقق مما إذا كانوا متأثرين بها، وتأكيد أن الترقية تحلّها. إن أداة docling الوهمية
على سطر الأوامر و«الأسرار» هي عناصر محلية خاملة. لا تستخدم هذه المواد ضد أنظمة لا تملكها أو لا تديرها.