
Рабочий воспроизводитель proof-of-concept для CVE-2026-79983 — обхода путей в потребителях Apache Camel camel-ftp, с фикстурами вредоносного FTP-сервера и сборками уязвимой и исправленной версий.
Запускаемый воспроизводитель proof-of-concept для уязвимости Apache Camel, при которой потребители удалённых файлов опрашивают
каталог на удалённом сервере и строят абсолютный удалённый путь каждого файла путём конкатенации настроенного
каталога с именем файла, указанным в листинге каталога сервера, без лексической нормализации и без
проверки, что результат остаётся внутри опрашиваемого каталога. Этот путь затем становится операндом для извлечения (всегда),
а также для удаления или переименования, когда настроены delete=true, move, preMove, moveFailed или readLock=rename.
Имя из листинга не является данными, контролируемыми маршрутом — оно предоставляется удалённым сервером, а канал управления FTP
не имеет защиты целостности, поэтому атакующий на пути может переписать ответ LIST, а скомпрометированный или мультитенантный
сервер может выдать такое имя напрямую. Документированная опция jailStartingDirectory, включённая по умолчанию, не ограничивала
этот удалённый операнд.
| Среда выполнения | Каталог | Стек |
|---|---|---|
| Camel Spring Boot | camel-spring-boot/ | Spring Boot 3.5.13 + camel-ftp 4.22.0 (уязвим; исправлено в 4.22.1) |
| Camel Quarkus | camel-quarkus/ | Quarkus 3.29.0 + camel-quarkus-ftp 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.
Приложение встраивает намеренно вредоносный FTP-сервер (Apache MINA FtpServer с VFS в памяти), который в листинге
опрашиваемого каталога /upload показывает:
normal.txt — легитимный файл внутри каталога, иd/../../outside.txt — специально сформированную запись, имя которой не является одним сегментом пути. Оно не начинается с точки
(поэтому правило Camel о скрытых файлах его не перехватывает), а /upload + d/../../outside.txt разрешается в /outside.txt,
на уровень выше опрашиваемого каталога.Обычный потребитель Camel FTP опрашивает /upload. В уязвимой сборке он извлекает обе записи — включая
/outside.txt, файл, до которого он не должен был добраться. В исправленной сборке он сохраняет normal.txt и пропускает выходящую за пределы
запись, записывая в лог Skipping file as it resolves outside the starting directory: upload/d/../../outside.txt.
cd camel-spring-boot
mvn clean package
docker compose up -d --build
curl -s http://localhost:8080/exploit/attack
docker compose down
Ожидаемый вывод на затронутой сборке:
What the Camel consumer retrieved:
name=[normal.txt] (inside)
name=[d/../../outside.txt] <<< FILE FROM OUTSIDE THE POLLED DIRECTORY
content: OUTSIDE-SECRET (/outside.txt, a file the consumer should never reach)
Paths the server was asked to read:
upload/normal.txt -> /upload/normal.txt
upload/d/../../outside.txt -> /outside.txt
| Свойство | Значение |
|---|---|
| Компонент | camel-ftp (схемы ftp, ftps, sftp) |
| CWE | CWE-22 (Некорректное ограничение пути к каталогу) |
| Критичность | ВЫСОКАЯ |
| Вектор атаки | Запись LIST (предоставляемая сервером, перезаписываемая по неаутентифицированному управляющему каналу FTP), которая не является одиночным сегментом пути |
| Воздействие | Чтение — а при delete/move/readLock=rename также удаление или переименование — файлов за пределами опрашиваемого каталога с использованием учётных данных эндпоинта |
| Уязвимые версии | С 4.0.0 до 4.18.5, с 4.19.0 до 4.22.1 |
| Исправленные версии | 4.18.5, 4.22.1, 4.23.0 |
| JIRA | CAMEL-24487 |
| Благодарность | Dilrevx из NSSL, SJTU |
Рекомендация: https://camel.apache.org/security/CVE-2026-79983.html
Перегрузка GenericFileHelper.isWithinDirectory с учётом разделителей и стратегия GenericFileConsumer.isWithinStartingDirectory
(вызываемая из isValidFile, когда включён jailStartingDirectory) нормализуют разрешённый путь и проверяют
на границах сегментов пути, что он по-прежнему разрешается внутри опрашиваемого каталога. Файл, разрешающийся за пределами,
пропускается с предупреждением (так что другие легитимные записи в том же листинге всё равно обрабатываются). RemoteFileConsumer и
SmbConsumer переопределяют проверку; локальная базовая реализация является пустой, поскольку имена в локальном листинге всегда
состоят из одного сегмента.
Предпочитайте sftp/ftps вместо ftp, чтобы листинг нельзя было перезаписать при передаче, и проверяйте ключ хоста/сертификат.
Ограничьте потребителя с помощью filter, antInclude или include, чтобы принимать только имена из одного сегмента, и избегайте
delete=true/move/preMove/moveFailed/readLock=rename при работе с серверами, чьи листинги не являются полностью доверенными.
Где возможно, ограничьте серверную учётную запись опрашиваемым каталогом.
Этот репозиторий публикуется в образовательных и защитных целях: чтобы помочь пользователям Apache Camel понять уязвимость, проверить, затронуты ли они, и убедиться, что обновление её устраняет. Вредоносный сервер и «секрет» являются инертными локальными фикстурами. Не используйте этот материал против систем, которыми вы не владеете и не управляете.