
أداة إثبات مفهوم قابلة للتشغيل لإعادة إنتاج CVE-2026-78162، تُظهر إزالة تسلسل Java دون مصادقة في Apache Camel camel-hazelcast عبر Spring Boot وQuarkus.
مُعيد إنتاج قابل للتشغيل (proof-of-concept) لثغرة Apache Camel حيث أنشأ camel-hazelcast نسخ Hazelcast
بدون JavaSerializationFilterConfig على مساري تهيئة لم يصلهما تحصين CVE-2026-43865
قط. على هذين المسارين، يقوم عضو/عميل Hazelcast الذي يبنيه Camel بإلغاء تسلسل القيم المقروءة من العنقود
دون أي تقييد على الفئات، لذا يمكن لمهاجم قادر على النشر في العنقود أن يجعل كائن Java مُسلسَلًا من
اختياره يُلغى تسلسله داخل طبقة التسلسل في Hazelcast — تنفيذ شيفرة عن بُعد (CWE-502). عناقيد Hazelcast
لا يكون فيها المصادقة ولا TLS مُفعَّلين افتراضيًا.
يقود مُعيد الإنتاج هذا أوضح المسارين: ReplicatedHazelcastAggregationRepository، الذي يتجاوز
doStart() دون استدعاء super.doStart()، وعلى بناء متأثر، يبدأ عضوه المحلي الخاص دون تطبيق
المرشّح الافتراضي. (المسار الشقيق، HazelcastDefaultComponent#getOrCreateHzClientInstance() من أجل
hazelcastMode=client، يغطيه الإصلاح نفسه.)
| بيئة التشغيل | الدليل | المكدّس |
|---|---|---|
| Camel Spring Boot | camel-spring-boot/ | Spring Boot 3.5.13 + camel-hazelcast 4.22.0 (متأثر؛ مُصلَح في 4.22.1) |
| Camel Quarkus | camel-quarkus/ | Quarkus 3.29.0 + camel-quarkus-hazelcast 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 مُصلَحًا (الأحدث، 3.29.0، على Camel 4.15.0)، لذا فإن وحدة Quarkus تُظهر الحالة المتأثرة فقط.
يشغّل التطبيق مسار Camel مدعومًا بـ ReplicatedHazelcastAggregationRepository بدون أي
HazelcastInstance مُقدَّم خارجيًا، لذا يبدأ المستودع عضو Hazelcast محليًا خاصًا به (العنقود الافتراضي dev، المنفذ 5701). على
البناء المتأثر، لا يملك ذلك العضو أي JavaSerializationFilterConfig.
ثم ينضم عميل مهاجم إلى العنقود وينشر كائنًا مُسلسَلًا في ReplicatedMap الداعم. عميل Hazelcast
يرسل البايتات فقط — ولا يخزّن قيم الخريطة أو يُلغي تسلسلها — لذا فإن أي إلغاء تسلسل يحدث
يُعزى إلى العضو الضحية. الكائن المنشور هو علامة حميدة عمدًا،
com.example.PwnMarker: لا يحمل أي سلسلة أدوات (gadget chain) ولا ينفّذ أي أمر، بل يسجّل فقط (عبر علم عام على مستوى JVM) أن
readObject الخاص به قد نُفِّذ. المهاجم الحقيقي كان سينشر فئة أدوات معروفة هنا بدلًا من ذلك، لتحقيق RCE — إثبات أن
الفئة قد أُلغي تسلسلها أصلًا كافٍ.
نظرًا لأن المرشّح الافتراضي للإصلاح هو قائمة بيضاء من بادئات أسماء الفئات java. وjavax. وorg.apache.camel.،
فإن com.example.PwnMarker هو الأداة الاستدلالية المثالية:
PwnMarker، ويُنفَّذ readObject على العضو الضحية → مُثبَت.com.example.PwnMarker قبل readObject → java.lang.SecurityException: Resolving class com.example.PwnMarker is not allowed → غير مُستغَل.cd camel-spring-boot
mvn clean package
docker compose up -d --build
curl -s http://localhost:8080/exploit/attack
docker compose down
الناتج المتوقع على إصدار متأثر:
=== CVE-2026-78162 — camel-hazelcast ReplicatedHazelcastAggregationRepository ===
=== missing JavaSerializationFilterConfig on the Camel-built member ===
Attacker client joined the victim cluster 'dev' at 127.0.0.1:5701.
Attacker published a com.example.PwnMarker into ReplicatedMap 'aggregation'.
Result:
>>> PROVEN: the Camel-built Hazelcast member deserialized an attacker-supplied, non-whitelisted
>>> class (com.example.PwnMarker) with no JavaSerializationFilterConfig in effect — its readObject
>>> executed inside the victim. A real attacker would publish a gadget class here instead, for RCE.
>>> PwnMarker.readObject executed inside the victim member; tag=attacker-rce-marker; thread=hz.*.partition-operation.thread-1
| الخاصية | القيمة |
|---|---|
| المكوّن | camel-hazelcast (camel-hazelcast-starter / camel-quarkus-hazelcast) |
| CWE | CWE-502 (إلغاء تسلسل البيانات غير الموثوقة) |
| الخطورة | متوسطة |
| ناقل الهجوم | مهاجم قادر على نشر نسخة مصابة داخل عنقود Hazelcast الذي يتصل به التطبيق؛ إذ يقوم العضو/العميل المبني بواسطة Camel بإلغاء تسلسل الكائن المنشور دون أي قيود على الفئات |
| التأثير | تنفيذ تعليمات برمجية عن بُعد داخل عملية Camel (عبر فئة أداة استغلال)، قبل أن يعالج Camel التبادل |
| الإصدارات المتأثرة | من 4.0.0 قبل 4.18.5، ومن 4.19.0 قبل 4.22.1 |
| الإصدارات المُصلحة | 4.18.5، 4.22.1، 4.23.0 |
| JIRA | CAMEL-24413، CAMEL-24420 |
| الفضل | cattier من TCBS؛ Leon Zlobecki |
الإشعار الأمني: https://camel.apache.org/security/CVE-2026-78162.html
اكتسب HazelcastSerializationFilterHelper.applyDefault(...) حمولة زائدة (overload) من نوع ClientConfig، ويُستدعى الآن على كلا
المسارين غير المُغطّيين سابقًا — ReplicatedHazelcastAggregationRepository#doStart() و
HazelcastDefaultComponent#getOrCreateHzClientInstance() — بحيث يحمل كل إعداد Hazelcast يبنيه Camel بنفسه
إعداد JavaSerializationFilterConfig الافتراضي (قائمة بيضاء java. / javax. / org.apache.camel.، وقائمة سوداء
java.net.). أما Config أو ClientConfig أو HazelcastInstance المقدَّم من المستخدم فيبقى دون مساس. هذا الإشعار
هو متابعة لإصلاح غير مكتمل لـ CVE-2026-43865.
قدّم إعداد Hazelcast صريحًا يحمل JavaSerializationFilterConfig، أو حقن HazelcastInstance مبني مسبقًا
(فالإعداد المقدَّم من المستخدم لا يُستبدل أبدًا بواسطة Camel)؛ اضبط على مستوى JVM الخيار
-Djdk.serialFilter=...؛ وفعّل مصادقة عنقود Hazelcast وTLS.
يُنشر هذا المستودع لأغراض تعليمية ودفاعية: لمساعدة مستخدمي Apache Camel على فهم الثغرة، والتحقق مما إذا كانوا متأثرين بها، وتأكيد أن الترقية تحلّها. الحمولة علامة حميدة لا تنفّذ أي تعليمات برمجية. لا تستخدم هذه المواد ضد أنظمة لا تملكها أو لا تديرها.