
Lauffähiger Proof-of-Concept-Reproduzierer für CVE-2026-101259, der die Offenlegung von Fehlermeldungen in Apache Camel camel-coap-Consumern unter Spring Boot und Quarkus demonstriert, sowie die Verifikation des Fixes.
Lauffähiger Proof-of-Concept-Reproducer für die Apache-Camel-Schwachstelle, bei der der CoAP-Consumer seine Antwort nach Abschluss der Route nicht erstellen konnte, CamelCoapResource die daraus resultierende Exception abfing und deren Nachricht als Payload eines 5.00 Internal Server Error an den CoAP-Client zurücksendete:
} catch (Exception e) {
cexchange.respond(ResponseCode.INTERNAL_SERVER_ERROR, e.getMessage());
}
| Laufzeitumgebung | Verzeichnis | Stack |
|---|---|---|
| Camel Spring Boot | camel-spring-boot/ | Spring Boot 3.5.13 + camel-coap 4.22.1 |
| Camel Quarkus | camel-quarkus/ | Camel Quarkus 3.39.0 (Quarkus 3.39.0, Camel 4.22.0) |
Der Consumer konvertiert den finalen Nachrichten-Body in die byte[]-Payload und die Header CamelCoapMaxAge und
CamelCoapETag in ihre Typen, nachdem die Route zurückgekehrt ist — und damit außerhalb des
Fehlerhandlers der Route. Ein onException in der Route kann dies nicht abfangen, da der Fehler im
Consumer auftritt, nicht in der Route.
cd camel-spring-boot # or: cd camel-quarkus
mvn clean package
docker compose up -d --build
until [ "$(curl -s http://localhost:8080/exploit/ready)" = "Started" ]; do sleep 1; done
curl -s http://localhost:8080/exploit/attack
docker compose down
Ausgabe auf einem betroffenen Build (identisch auf beiden Runtimes):
1) Converting the body to the byte[] payload fails once the route has completed
CoAP GET coap://127.0.0.1:5683/reading
response code : 5.00 (INTERNAL_SERVER_ERROR)
response payload : Error during type conversion from type: com.example.FailingBackendStream to the
required type: byte[] with value com.example.FailingBackendStream@5eede7d7 due to
java.io.IOException: connection to prod-db.internal:5432 reset while streaming
sensor_readings for node edge-gateway-07.dc2.internal
2) The CamelCoapMaxAge header cannot be converted to its type
CoAP GET coap://127.0.0.1:5683/reading-maxage
response code : 5.00 (INTERNAL_SERVER_ERROR)
response payload : Error during type conversion from type: java.lang.String to the required type:
java.lang.Long with value not-a-number due to java.lang.NumberFormatException:
For input string: "not-a-number"
3) A route that simply fails
CoAP GET coap://127.0.0.1:5683/reading-failing
response code : 2.05 (CONTENT)
response payload : partially built response
What a remote CoAP client learned from these responses:
the backend host and port, out of the cause's message : true
class names of the cause : true
the source and target types of the conversion : true
the string form of the offending value : true
a failed route answered with a SUCCESS code : true
>>> PROVEN: ...
Die Meldung eines solchen Fehlers nennt die Klasse des Werts, der konvertiert wird, enthält die String-Form des Werts und endet mit dem Klassennamen und der Meldung der zugrunde liegenden Ursache — ein entfernter CoAP-Client las also Klassen- und Paketnamen, die String-Form des Werts und alles, was die Ursache mitführt, was in der Praxis Pfade, Hostnamen und Verbindungsdetails eines Backends umfassen kann. Der Consumer hatte keine Möglichkeit, dies zu unterdrücken, anders als die HTTP-Consumer, die zu diesem Zweck muteException anbieten.
Probe 3 ist die zweite Hälfte des Problems. Die von einer fehlschlagenden Route ausgelöste Exception wurde überhaupt nicht gesendet: Der Consumer prüfte nicht, ob der Exchange fehlgeschlagen war, und beantwortete einen Routenfehler mit 2.05 Content und dem Body, den die Nachricht zu diesem Zeitpunkt enthielt — ein Erfolgscode für eine fehlgeschlagene Route.
Eine Sache musste dieser Reproducer richtig hinbekommen: Ein Body, für den kein Konverter existiert, reicht nicht aus.
getBody(byte[].class)gibt in diesem Fallnullzurück, statt eine Exception zu werfen, und der Consumer antwortet dann mit2.05und einer leeren Payload — keine Offenlegung. Die Konvertierung muss fehlschlagen, nicht nicht verfügbar sein, weshalb Probe 1 einen Stream-Body verwendet, der mitten in einem Lesevorgang eine Exception wirft. Die Header-Probe schlägt auf die andere Weise fehl, durch einen Wert der falschen Form.
Das Erreichen der Offenlegung erfordert eine Route, deren abgeschlossene Antwort ein entfernter Client unkonvertierbar machen kann, was davon abhängt, wie die Route geschrieben ist. Nichts davon ist authentifiziert, und einfache CoAP-GETs sind alles, was der Client sendet.
| Eigenschaft | Wert |
|---|---|
| Komponente | camel-coap (CamelCoapResource) |
| CWE | CWE-209 (Generation of Error Message Containing Sensitive Information) |
| Schweregrad | Mittel |
| Angriffsvektor | Eine CoAP-Anfrage an einen Consumer, dessen abgeschlossene Antwort nicht erstellt werden kann — ein Body, dessen Konvertierung zu byte[] fehlschlägt, oder ein CamelCoapMaxAge- / CamelCoapETag-Header, dessen Konvertierung fehlschlägt |
| Auswirkung | Ein entfernter CoAP-Client liest Klassen- und Paketnamen, die String-Form des Werts und die Meldung der zugrunde liegenden Ursache — in der Praxis Pfade, Hostnamen und Backend-Verbindungsdetails |
| Betroffene Versionen | Ab 4.0.0 vor 4.18.5, ab 4.19.0 vor 4.22.2 |
| Behobene Versionen | 4.18.5, 4.22.2, 4.23.0 |
| JIRA | CAMEL-25087 |
| Danksagung | Zhixi "Jace" Sun, unabhängiger Sicherheitsforscher |
Advisory: https://camel.apache.org/security/CVE-2026-101259.html
Der Consumer erhält eine muteException-Option — bei den Endpunkten coap, coaps, coap+tcp und coaps+tcp
gleichermaßen —, die standardmäßig auf allen drei behobenen Release-Linien true ist, sodass das Upgrade allein ausreicht
und keine Konfigurationsänderung erforderlich ist. Der Consumer antwortet weiterhin mit 5.00 Internal Server Error, aber mit einer
leeren Payload, und er meldet die Exception nun über den Exception-Handler des Consumers, sodass das Stummschalten sie
nicht vor dem Betreiber verbirgt.
Er prüft außerdem, ob der Exchange fehlgeschlagen ist, und beantwortet einen Routenfehler mit 5.00 Internal Server Error
unter derselben Regel, wo er zuvor mit 2.05 Content geantwortet hat.
Behoben auf main in apache/camel#26994 (2245feac), zurückportiert
nach camel-4.22.x in #27046 (868d5604) und nach camel-4.18.x
in #27048 (aaf5bbf8).
Setzen Sie camel.version auf 4.22.2 und führen Sie es erneut aus. Verifiziert gegen 4.22.1 → 4.22.2:
1) ... response code: 5.00 (INTERNAL_SERVER_ERROR) response payload : <empty>
2) ... response code: 5.00 (INTERNAL_SERVER_ERROR) response payload : <empty>
3) ... response code: 5.00 (INTERNAL_SERVER_ERROR) response payload : <empty>
>>> NOT reproduced: the error payload was empty.
Probe 3 ändert ebenfalls den Code, von 2.05 Content zu 5.00 Internal Server Error — der Routenfehler wird nun
als Fehler beantwortet.