
Proof-of-concept eseguibile che riproduce CVE-2026-78163 in Apache Camel camel-docling, dimostrando SSRF e divulgazione di file locali tramite input String body non validato, con controllo su build corretta.
Proof-of-concept riproducibile ed eseguibile per la vulnerabilità di Apache Camel in cui DoclingProducer decideva il significato di un body di messaggio di tipo String ispezionandone il prefisso:
http:// o https:// veniva passato a Docling come URL remoto da recuperare (SSRF), e/ (o conteneva un backslash) veniva letto dal filesystem locale (divulgazione di file).La modalità veniva scelta implicitamente, senza alcuna opzione dell'endpoint per fissare una singola interpretazione e — a differenza del namespace degli header di Camel — il body del messaggio non viene mai filtrato da un HeaderFilterStrategy. Così una route che intende "convertire qualunque testo arrivi nel body" diventava silenziosamente un recuperatore di risorse remote o un lettore di file locali ogni volta che il testo controllato dall'attaccante iniziava con uno di quei prefissi.
| Runtime | Directory | Stack | Mostra |
|---|---|---|---|
| Camel Spring Boot | camel-spring-boot/ | Spring Boot 3.5.13 + camel-docling 4.22.0 (affetto; corretto in 4.22.1) | SSRF e divulgazione di file, più il controllo con build corretta |
| Camel Quarkus | camel-quarkus/ | Quarkus 3.29.0 + camel-quarkus-docling 3.29.0 (Camel 4.15.0, affetto) | solo divulgazione di file (vedi nota) |
Copertura delle versioni. Il sink di divulgazione di file locali esiste da quando camel-docling è stato introdotto nella 4.15.0; il sink per URL remoti è stato aggiunto nella 4.16.0 con il supporto a docling-serve. L'ultima versione di Camel Quarkus (3.29.0) include Camel 4.15.0, quindi il suo modulo dimostra solo la divulgazione di file. La correzione è inclusa in Camel 4.18.5 / 4.22.1 / 4.23.0; il modulo Spring Boot esegue sia la build affetta (4.22.0) sia quella corretta (4.22.1), quindi dimostra anche il comportamento corretto. Nessuna versione rilasciata di Camel Quarkus include ancora un Camel corretto.
Nessuno dei due reproducer necessita di un'installazione reale di Docling: una piccola CLI finta docling (fake-docling/docling) sostituisce
il binario e rende visibile ciò che quello reale farebbe con l'input fornito dal producer — recuperare un URL o leggere un
file. È benigna: si limita a restituire ciò che le è stato detto di elaborare e registra la propria invocazione. Il punto della CVE è
che un body fornito dall'attaccante raggiunge quell'argomento, senza alcun opt-in.
L'app Spring Boot esegue anche un endpoint HTTP solo interno su 127.0.0.1:9099 (solo la porta 8080 è pubblicata,
quindi un client esterno non può raggiungere direttamente la 9099) e un file segreto locale. L'attaccante invia solo testo:
http://127.0.0.1:9099/internal-secret → l'invocazione di docling lato server recupera
l'endpoint interno e il suo segreto viene restituito al chiamante./tmp/cve-2026-78163-secret.txt → il file locale viene letto e restituito.Sulla build affetta entrambi riescono; sulla build corretta entrambi vengono rifiutati con un IllegalArgumentException
che nomina l'opzione (allowUrlSource / allowFilePathSource) che sarebbe necessaria per abilitarli, e docling non
viene mai invocato.
cd camel-spring-boot
mvn clean package
docker compose up -d --build
curl -s http://localhost:8080/exploit/attack
docker compose down
Output previsto sulla build Spring Boot interessata:
[1] SSRF — sending body = http://127.0.0.1:9099/internal-secret
>>> PROVEN SSRF: the server-side docling invocation fetched the attacker-controlled internal URL.
>>> internal victim saw: [GET /internal-secret]
>>> content returned to the caller:
| INTERNAL-SECRET-DATA (only reachable from inside the deployment)
[2] File disclosure — sending body = /tmp/cve-2026-78163-secret.txt
>>> PROVEN file disclosure: the attacker-named local file was read and returned.
| TOP-SECRET-FILE-CONTENT (local file an attacker should not be able to read)
| Proprietà | Valore |
|---|---|
| Componente | camel-docling (camel-docling-starter / camel-quarkus-docling) |
| CWE | CWE-918 (SSRF), CWE-22 (Path Traversal), CWE-200 (Esposizione di informazioni) |
| Gravità | MEDIA |
| Vettore di attacco | Un corpo del messaggio di tipo String inoltrato verso un endpoint docling, il cui prefisso seleziona un sink di recupero URL o di lettura file; il corpo non è soggetto a HeaderFilterStrategy |
| Impatto | Recupero lato server di URL scelti dall'attaccante (servizi interni) e divulgazione di file locali |
| Versioni interessate | Dalla 4.15.0 precedente alla 4.18.5, dalla 4.19.0 precedente alla 4.22.1 (divulgazione di file dalla 4.15.0; sink URL dalla 4.16.0) |
| Versioni corrette | 4.18.5, 4.22.1, 4.23.0 |
| JIRA | CAMEL-24422 |
| Credito | Li Zhiyao (BUPT) |
Avviso: https://camel.apache.org/security/CVE-2026-78163.html
Un corpo di tipo String viene ora trattato per impostazione predefinita come il documento stesso. Le due interpretazioni di posizione sono diventate opt-in tramite
le nuove opzioni dell'endpoint allowUrlSource e allowFilePathSource (entrambe predefinite a false); un corpo che sembra un URL
o un percorso viene altrimenti rifiutato con un'IllegalArgumentException che indica l'opzione che lo abiliterebbe. Un'ulteriore
opzione inputBaseDirectory confina i percorsi di input locali in una directory configurata. I corpi tipizzati (File, byte[],
InputStream) e l'header CamelDoclingInputFilePath dichiarano già il loro significato e non sono soggetti a restrizioni (ma restano
soggetti a inputBaseDirectory).
Non instradare corpi di messaggi di origine esterna verso un endpoint docling; passare il documento tramite un corpo tipizzato
(File, byte[], InputStream) o l'header CamelDoclingInputFilePath in modo che il corpo non sia mai soggetto all'interpretazione
del prefisso.
Questo repository è pubblicato per scopi educativi e difensivi: per aiutare gli utenti di Apache Camel a comprendere la
vulnerabilità, verificare se sono interessati e confermare che l'aggiornamento la risolve. La CLI docling fittizia e
i "segreti" sono fixture locali inerti. Non utilizzare questo materiale contro sistemi di cui non si è proprietari o gestori.