
Lauffähiger Spring Boot- und Quarkus-Reproducer für CVE-2026-91858, eine XXE-Schwachstelle in Apache Camel camel-fop über eine TransformerFactory eines Drittanbieters, mit Verifikation der betroffenen und der gepatchten Version.
Lauffähiger Proof-of-Concept-Reproduzierer für die Apache-Camel-Schwachstelle, bei der camel-fops FopProducer seine
javax.xml.transform.TransformerFactory nur mit FEATURE_SECURE_PROCESSING erstellte, bevor eine Identitätstransformation
über den XSL-FO-Nachrichtentext ausgeführt wurde. Beim integrierten Transformer des JDK leert dieses Feature allein bereits die
Grenzwerte accessExternalDTD/accessExternalStylesheet, sodass externe Ressourcen abgelehnt werden. Wenn sich jedoch eine
JAXP-TransformerFactory eines Drittanbieters wie Saxon-HE im Klassenpfad befindet — z. B. weil die Anwendung auch
camel-xslt-saxon oder camel-saxon verwendet —, gibt TransformerFactory.newInstance() diese Implementierung zurück, und
FEATURE_SECURE_PROCESSING allein schränkt den Zugriff auf externe Ressourcen dort nicht ein. Eine DOCTYPE mit einer im
XSL-FO-Text deklarierten externen Teilmenge wird dann während der Transformation des Textes aufgelöst, sodass ein Dokument
eines externen Absenders Dateien lesen kann, die für den Camel-Prozess lesbar sind, oder ihn dazu bringen kann, Anfragen an von
ihm benannte Hosts zu senden (CWE-611).
| Laufzeitumgebung | Verzeichnis | Stack |
|---|---|---|
| Camel Spring Boot | camel-spring-boot/ | Spring Boot 3.5.13 + camel-fop 4.22.0 (betroffen; behoben in 4.22.1) + Saxon-HE 13.0 |
| Camel Quarkus | camel-quarkus/ | Quarkus 3.39.0 + camel-quarkus-fop (Camel 4.22.0, betroffen; behobene Kontrolle CQ 3.40.0 / Camel 4.22.1) + Saxon-HE 13.0 |
Beide Module demonstrieren das betroffene und das behobene Verhalten gegenüber dem echten FopProducer. Saxon-HE befindet
sich in beiden im Klassenpfad — es ist die Voraussetzung für die Schwachstelle; eine Standardbereitstellung mit dem
JDK-Transformer ist vor und nach der Behebung nicht betroffen.
Der Verifier-Endpunkt /exploit/attack startet einen prozessinternen HTTP-Callback und sendet ein XSL-FO-Dokument an fop:pdf,
dessen DOCTYPE eine externe DTD deklariert, die auf diesen Callback verweist:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE fo:root SYSTEM "http://localhost:<port>/external.dtd">
<fo:root …>…Hello…</fo:root>
Das Orakel ist einfach ob der Callback angefordert wurde — ein definitiver Beweis dafür, dass die externe Ressource abgerufen wurde:
TransformerFactory.newInstance() gibt Saxon zurück, das allein unter Secure Processing dennoch die
externe DTD abruft — der Callback wird ausgelöst (derselbe Mechanismus liest file://-URLs).ACCESS_EXTERNAL_DTD ist auf "" gesetzt, sodass Saxon die externe DTD verweigert; der Callback wird nie ausgelöst.# Camel Spring Boot
cd camel-spring-boot
mvn clean package
docker compose up -d --build
curl -s http://localhost:8080/exploit/attack # affected: callback hit = true; >>> PROVEN
docker compose down
# Patched control
mvn clean package -Dcamel.version=4.22.1
java -Djava.awt.headless=true -jar target/cve-2026-91858-fop-xxe-0.0.1-SNAPSHOT.jar &
curl -s http://localhost:8080/exploit/attack # fixed: callback hit = false; >>> Not exploited
# Camel Quarkus
cd camel-quarkus
mvn clean package
docker compose up -d --build
curl -s http://localhost:8080/exploit/attack # affected (Camel 4.22.0): callback hit = true
docker compose down
# Patched control: CQ 3.40.0 ships Camel 4.22.1
mvn clean package -Dcamel-quarkus.version=3.40.0 -Dquarkus.platform.version=3.40.0
java -Djava.awt.headless=true -jar target/quarkus-app/quarkus-run.jar &
curl -s http://localhost:8080/exploit/attack # fixed: callback hit = false
| Eigenschaft | Wert |
|---|---|
| Komponente | camel-fop (FopProducer) |
| CWE | CWE-611 (Improper Restriction of XML External Entity Reference) |
| Schweregrad | MITTEL |
| Angriffsvektor | Das XSL-FO eines externen Absenders erreicht einen fop:-Producer in einer Bereitstellung, die zusätzlich eine JAXP-TransformerFactory eines Drittanbieters (z. B. Saxon-HE) im Classpath enthält |
| Auswirkung | Lesen lokaler Dateien, die für den Camel-Prozess lesbar sind; SSRF zu internen Hosts, die das Dokument benennt |
| Betroffene Versionen | Ab 4.0.0 vor 4.18.5, ab 4.19.0 vor 4.22.1 (nur bei Vorhandensein einer Nicht-JDK-TransformerFactory) |
| Behobene Versionen | 4.18.5, 4.22.1, 4.23.0 |
| JIRA | CAMEL-24605 |
| Danksagung | Claude Security Scan Tool |
Advisory: https://camel.apache.org/security/CVE-2026-91858.html
Das betroffene Quarkus-Modul basiert auf CQ 3.39.0 (Camel 4.22.0). Die gepatchte Kontrolle ist CQ 3.40.0 (Camel 4.22.1). Saxon-HE 13.0 wird beiden Modulen hinzugefügt als Stellvertreter für eine Anwendung, die auch camel-xslt-saxon/camel-saxon verwendet; ohne eine Nicht-JDK-TransformerFactory ist die Schwachstelle nicht erreichbar.
FopProducer setzt nun zusätzlich XMLConstants.ACCESS_EXTERNAL_DTD und
XMLConstants.ACCESS_EXTERNAL_STYLESHEET auf die leere Zeichenkette bei der von ihm erzeugten TransformerFactory (zusätzlich zu
FEATURE_SECURE_PROCESSING), was der sicheren XML-Verarbeitungskonfiguration entspricht, die von XmlConverter verwendet wird. Der Zugriff auf externe DTDs und Stylesheets wird daher bei jeder JAXP-Implementierung verweigert, die diese Attribute berücksichtigt, einschließlich Saxon-HE.
Senden Sie kein nicht vertrauenswürdiges XSL-FO an einen fop:-Producer oder entfernen Sie die alternative JAXP-TransformerFactory (wie
Saxon-HE) aus dem Classpath, sodass der JDK-Transformer – der externe DTDs unter sicherer Verarbeitung bereits verweigert – verwendet wird.
Dieses Repository wird zu Bildungs- und Verteidigungszwecken veröffentlicht: um Apache-Camel-Nutzern zu helfen, die Schwachstelle zu verstehen, zu prüfen, ob sie betroffen sind, und zu bestätigen, dass ein Upgrade sie behebt. Die externe DTD verweist auf einen In-Process-Callback auf localhost; es wird nichts außerhalb des Reproducers kontaktiert und keine sensible Datei gelesen. Verwenden Sie dieses Material nicht gegen Systeme, die Ihnen nicht gehören oder die Sie nicht betreiben.