
Работоспособный воспроизводитель proof-of-concept для CVE-2026-78163 в Apache Camel camel-docling, демонстрирующий SSRF и раскрытие локальных файлов через невалидированный ввод String body, с контролем на исправленной сборке.
Запускаемый воспроизводитель proof-of-concept для уязвимости Apache Camel, в которой DoclingProducer определял,
что означает тело сообщения String, путём проверки его префикса:
http:// или https://, передавалось Docling как удалённый URL для загрузки (SSRF), а/ (или содержащее обратную косую черту), читалось из локальной файловой системы (раскрытие файлов).Режим выбирался неявно, без опции эндпоинта для фиксации единственной интерпретации, и — в отличие от пространства
имён заголовков Camel — тело сообщения никогда не фильтруется через HeaderFilterStrategy. Поэтому маршрут,
который подразумевает «преобразовать любой текст, пришедший в теле», незаметно превращался в загрузчик удалённых
ресурсов или читатель локальных файлов всякий раз, когда контролируемый атакующим текст начинался с одного из этих
префиксов.
| Среда выполнения | Каталог | Стек | Демонстрирует |
|---|---|---|---|
| Camel Spring Boot | camel-spring-boot/ | Spring Boot 3.5.13 + camel-docling 4.22.0 (уязвимая; исправлено в 4.22.1) | SSRF и раскрытие файлов, а также контроль на исправленной сборке |
| Camel Quarkus | camel-quarkus/ | Quarkus 3.29.0 + camel-quarkus-docling 3.29.0 (Camel 4.15.0, уязвимая) | только раскрытие файлов (см. примечание) |
Покрытие версий. Сток раскрытия локальных файлов существует с момента появления camel-docling в 4.15.0; сток удалённого URL был добавлен в 4.16.0 вместе с поддержкой docling-serve. Последняя версия Camel Quarkus (3.29.0) включает Camel 4.15.0, поэтому её модуль демонстрирует только раскрытие файлов. Исправление поставляется в Camel 4.18.5 / 4.22.1 / 4.23.0; модуль Spring Boot запускает как уязвимую сборку (4.22.0), так и исправленную сборку (4.22.1), поэтому он также демонстрирует исправленное поведение. Ни одна выпущенная версия Camel Quarkus пока не включает исправленный Camel.
Ни одному из воспроизводителей не нужна настоящая установка Docling: крошечный поддельный CLI docling (fake-docling/docling) заменяет
бинарник и делает видимым то, что сделал бы настоящий с переданным продюсером входом — загрузил бы URL или прочитал
файл. Он безвреден: он лишь возвращает то, что ему велели обработать, и логирует собственный вызов. Суть CVE в том,
что предоставленное атакующим тело вообще доходит до этого аргумента, без явного включения.
Приложение Spring Boot также запускает внутренний HTTP-эндпоинт на 127.0.0.1:9099 (публикуется только порт 8080,
поэтому внешний клиент не может напрямую обратиться к 9099) и локальный файл с секретом. Атакующий отправляет только текст:
http://127.0.0.1:9099/internal-secret → серверный вызов docling загружает
внутренний эндпоинт, и его секрет возвращается вызывающему./tmp/cve-2026-78163-secret.txt → локальный файл читается и возвращается.На уязвимой сборке обе атаки успешны; на исправленной сборке обе отклоняются с IllegalArgumentException,
указывающим опцию (allowUrlSource / allowFilePathSource), которая потребовалась бы для их включения, и docling
никогда не вызывается.
cd camel-spring-boot
mvn clean package
docker compose up -d --build
curl -s http://localhost:8080/exploit/attack
docker compose down
Ожидаемый вывод при сборке затронутого Spring Boot:
[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)
| Свойство | Значение |
|---|---|
| Компонент | camel-docling (camel-docling-starter / camel-quarkus-docling) |
| CWE | CWE-918 (SSRF), CWE-22 (Path Traversal), CWE-200 (Information Exposure) |
| Критичность | MEDIUM |
| Вектор атаки | Тело сообщения типа String, передаваемое в эндпоинт docling, префикс которого выбирает приёмник для загрузки URL или чтения файла; тело не подпадает под действие HeaderFilterStrategy |
| Воздействие | Загрузка на стороне сервера URL, выбранных атакующим (внутренние сервисы), и раскрытие локальных файлов |
| Затронутые версии | С 4.15.0 до 4.18.5, с 4.19.0 до 4.22.1 (раскрытие файлов с 4.15.0; приёмник URL с 4.16.0) |
| Исправленные версии | 4.18.5, 4.22.1, 4.23.0 |
| JIRA | CAMEL-24422 |
| Благодарность | Li Zhiyao (BUPT) |
Уведомление: https://camel.apache.org/security/CVE-2026-78163.html
Тело типа String теперь по умолчанию рассматривается как сам документ. Два способа интерпретации местоположения стали опциональными благодаря
новым параметрам эндпоинта allowUrlSource и allowFilePathSource (оба по умолчанию false); тело, которое выглядит как URL
или путь, в противном случае отклоняется с IllegalArgumentException, в котором указан параметр, позволяющий его включить. Дополнительный
параметр inputBaseDirectory ограничивает локальные входные пути настроенным каталогом. Типизированные тела (File, byte[],
InputStream) и заголовок CamelDoclingInputFilePath уже явно задают своё назначение и не ограничиваются (но по-прежнему
подпадают под действие inputBaseDirectory).
Не направляйте тела сообщений из внешних источников в эндпоинт docling; передавайте документ через типизированное тело
(File, byte[], InputStream) или заголовок CamelDoclingInputFilePath, чтобы тело никогда не подвергалось интерпретации
префикса.
Этот репозиторий публикуется в образовательных и защитных целях: чтобы помочь пользователям Apache Camel понять
уязвимость, проверить, затронуты ли они, и убедиться, что обновление её устраняет. Поддельный CLI docling и
«секреты» — это инертные локальные фикстуры. Не используйте этот материал против систем, которыми вы не владеете и не управляете.