
CVE-2026-71569 के लिए रन करने योग्य Docker प्रूफ-ऑफ-कॉन्सेप्ट, जो Apache Camel camel-a2a वेबहुक सत्यापन में एक SSRF गार्ड बायपास है, जिसमें प्रोब और फिक्स सत्यापन शामिल हैं।
Apache Camel भेद्यता के लिए चलाने योग्य प्रूफ-ऑफ-कॉन्सेप्ट पुनरुत्पादक, जहाँ WebhookUrlValidator ने पुश-नोटिफिकेशन वेबहुक होस्ट को दो स्थानों पर वर्गीकृत किया जो एक-दूसरे से मेल नहीं खाते थे:
fc00::/7 ("fc", "fd") को नामित करते हैं;isLoopbackAddress,
isAnyLocalAddress, isLinkLocalAddress तथा isSiteLocalAddress के साथ वर्गीकृत किया गया।ये प्रेडिकेट्स एक ही क्षेत्र को कवर नहीं करते: isSiteLocalAddress पदावनत fec0::/10
ब्लॉक की रिपोर्ट करता है, न कि उसकी जगह लेने वाले fc00::/7 यूनिक लोकल पतों की, और JDK में
उनके लिए कोई प्रेडिकेट ही नहीं है। इसलिए वही पता इस बात पर निर्भर करते हुए स्वीकार या अस्वीकार किया जाता था कि वह कैसे लिखा गया था।
| रनटाइम | निर्देशिका | स्टैक |
|---|---|---|
| Camel Spring Boot | camel-spring-boot/ | Spring Boot 3.5.13 + camel-a2a 4.22.1 |
| Camel Quarkus | camel-quarkus/ | Camel Quarkus 3.39.0 (Quarkus 3.39.0, Camel 4.22.0) |
होस्ट नाम को fc00::/7 में रिज़ॉल्व होना चाहिए, जिसे compose फ़ाइल एक extra_hosts प्रविष्टि
के माध्यम से व्यवस्थित करती है (Docker इसे स्टार्ट-अप पर कंटेनर की /etc/hosts में लिखता है) — इसलिए इसे Docker के माध्यम से चलाएँ, सादे java -jar के साथ नहीं:
cd camel-spring-boot # or: cd camel-quarkus
mvn clean package
docker compose up -d --build
until curl -sf http://localhost:8080/exploit/ready >/dev/null; do sleep 1; done
curl -s http://localhost:8080/exploit/attack
docker compose down
प्रभावित बिल्ड पर आउटपुट (दोनों रनटाइम पर समान):
Resolution in this environment: internal-service.example -> fd00:0:0:0:0:0:0:1
1) The unique local address as an IP LITERAL
url: https://[fd00::1]/push-notification
verdict: REFUSED - Webhook URL must not point to private/internal IPv6 ranges (SSRF protection): [fd00::1]
2) The SAME address reached through a host name
url: https://internal-service.example/push-notification
verdict: ACCEPTED, resolved to fd00:0:0:0:0:0:0:1
3) A legitimate host name that merely BEGINS with "fc" (the bug's other direction)
url: https://fcm.googleapis.com/push-notification
verdict: REFUSED - Webhook URL must not point to private/internal IPv6 ranges (SSRF protection): fcm.googleapis.com
4) CONTROL - an IPv4 private address, which isSiteLocalAddress does cover
verdict: REFUSED - ... site-local/private address ...
5) CONTROL - a link-local IPv6 literal
verdict: REFUSED - ... private/internal IPv6 ranges ...
>>> PROVEN: ...
जाँच 1 और 2 एक ही पता हैं, और निर्णय असहमत हैं। जाँच 3 विपरीत दिशा में वही असंगति है: स्ट्रिंग पूर्व-जाँच ने कच्चे होस्ट से मेल खाया बिना पहले यह स्थापित किए कि यह एक IP लिटरल था, इसलिए कोई भी नाम जो केवल fc या fd से शुरू होता था, सीधे अस्वीकार कर दिया गया — fcm.googleapis.com, जो एक पूरी तरह सामान्य पुश एंडपॉइंट है, उनमें से एक है। जाँच 4 और 5 नियंत्रण हैं जो दर्शाते हैं कि गार्ड वहाँ काम कर रहा है जहाँ इसे सही ढंग से लिखा गया था।
प्रत्येक जाँच allowLocal=false पास करती है, जो डिफ़ॉल्ट है (allowLocalWebhookUrls=false) और वह कॉन्फ़िगरेशन है जिसमें गार्ड के कायम रहने की अपेक्षा है।
वेबहुक URL TaskPushNotificationConfig.url के रूप में उस कॉलर से आता है जो पुश नोटिफिकेशन पंजीकृत कर रहा है, इसलिए यह हमलावर-नियंत्रित है। इसके बाद PushNotificationDispatcher पुश नोटिफिकेशन को उस पते पर भेजता है, साथ में उसी कॉन्फ़िगरेशन में मौजूद कोई भी Authorization हेडर भी — जिसकी स्कीम और क्रेडेंशियल पंजीकरण करने वाला कॉलर प्रदान करता है।
प्रतिक्रिया उस कॉलर को वापस रिले नहीं की जाती, इसलिए इससे जो प्राप्त होता है वह Camel प्रक्रिया से एक आंतरिक पते तक एक ब्लाइंड आउटबाउंड HTTPS अनुरोध है जिसे अस्वीकार करने के लिए गार्ड लिखा गया था। उस तरह से किसी सेवा तक पहुँचने के लिए अतिरिक्त रूप से आवश्यक है कि नाम लक्ष्य वातावरण में fc00::/7 में रिज़ॉल्व हो, कि उस पते पर कोई HTTPS सेवा सुन रही हो, और कि अनुरोध किए जा रहे नाम के लिए TLS हैंडशेक सफल हो — यही कारण है कि गंभीरता को मध्यम आँका गया है।
| गुण | मान |
|---|---|
| घटक | camel-a2a (WebhookUrlValidator) |
| CWE | CWE-918 (सर्वर-साइड रिक्वेस्ट फ़ॉर्जरी) |
| गंभीरता | मध्यम |
| हमला वेक्टर | एक पुश-नोटिफिकेशन वेबहुक URL जिसका होस्ट नाम fc00::/7 में रिज़ॉल्व होता है |
| प्रभाव | कॉन्फ़िगर किए गए Authorization हेडर के साथ, एक आंतरिक पते तक एक ब्लाइंड आउटबाउंड HTTPS अनुरोध, जिसे गार्ड को अस्वीकार करना चाहिए था |
| प्रभावित संस्करण | 4.21.0 से 4.22.2 से पहले तक |
| ठीक किए गए संस्करण | 4.22.2, 4.23.0 |
| JIRA | CAMEL-24371 |
| श्रेय | 2122295973 at qq dot com, ASF सुरक्षा टीम के माध्यम से रिपोर्ट किया गया |
सलाह: https://camel.apache.org/security/CVE-2026-71569.html
अब दोनों पथ InetAddress.getByName से होकर गुज़रते हैं, जो एक ब्रैकेटेड IPv6 लिटरल को DNS को छुए बिना पार्स करता है, और परिणामी पते को उसके कच्चे बाइट्स से एक साझा क्लासिफायर के साथ वर्गीकृत करता है — इसलिए किसी होस्ट का मूल्यांकन उस पते से होता है जिसे वह दर्शाता है, न कि इससे कि उसे कैसे लिखा गया था। वह क्लासिफायर fc00::/7 और साझा पता स्थान 100.64.0.0/10, साथ ही IPv4-संगत, NAT64 (64:ff9b::/96) और 6to4 (2002::/16) पतों को पहचानता है जिनका अंतर्निहित IPv4 पता वैश्विक रूप से रूटेबल नहीं है।
main पर apache/camel#25406 (54041cce) में ठीक किया गया, camel-4.22.x में #26583 (c4a5c5fc) में बैकपोर्ट किया गया।
camel.version को 4.22.2 पर सेट करें और इसे फिर से चलाएँ। 4.22.1 → 4.22.2 के विरुद्ध सत्यापित:
1) The unique local address as an IP LITERAL
verdict: REFUSED - Webhook URL must not point to a unique local address (SSRF protection): [fd00::1]
2) The SAME address reached through a host name
verdict: REFUSED - Webhook URL must not point to a unique local address (SSRF protection): internal-service.example
3) A legitimate host name that merely BEGINS with "fc"
verdict: ACCEPTED, resolved to 216.239.38.55
अब दोनों स्पेलिंग को समान निर्णय मिलता है, समान संदेश के साथ, और probe 3 में मौजूद false positive भी हट गया है।
A2A push-notification कॉन्फ़िगरेशन पथ के सामने प्रमाणीकरण रखें ताकि webhook URL किसी अविश्वसनीय कॉलर से
न आए, और नेटवर्क स्तर पर Camel प्रक्रिया से fc00::/7 तक egress को अस्वीकार करें।
जहाँ डिप्लॉयमेंट को IPv6 की आवश्यकता नहीं है, वहाँ JVM को -Djava.net.preferIPv4Stack=true के साथ शुरू करने से
वह address class हट जाती है जिस पर यह अंतराल निर्भर है। ध्यान दें कि allowLocalWebhookUrls=false पहले से ही डिफ़ॉल्ट है और
अपने आप में इस अंतराल को बंद नहीं करता — ऊपर दिया गया probe 2 इसी के साथ चलता है।
यह रिपॉज़िटरी शैक्षिक और रक्षात्मक उद्देश्यों के लिए प्रकाशित की गई है: Apache Camel उपयोगकर्ताओं को इस भेद्यता को समझने, यह सत्यापित करने कि क्या वे प्रभावित हैं, और यह पुष्टि करने में मदद करने के लिए कि अपग्रेड करने से यह हल हो जाती है। इस सामग्री का उपयोग उन सिस्टमों के विरुद्ध न करें जो आपके स्वामित्व या संचालन में नहीं हैं।