
Эксплойты-репроducers для уязвимости обхода пути (path traversal) в Apache Camel (CVE-2026-60093) в camel-azure-storage-datalake, демонстрирующие произвольную запись файлов через downloadToFile.
downloadToFile: обход путиГотовые к запуску proof-of-concept-репродукторы одной и той же уязвимости Apache Camel, по одному на каждую среду выполнения:
| Среда выполнения | Каталог | Стек |
|---|
| Camel Spring Boot | camel-spring-boot/ | Spring Boot 3.5.13 + camel-azure-storage-datalake 4.18.2 |
| Camel Quarkus | camel-quarkus/ | Quarkus 3.36.0 + Camel Quarkus 3.36.0 (включает Camel 4.20.0) |
Обе — затронутые версии (проблема исправлена в 4.14.9 / 4.18.4 / 4.22.0), и обе демонстрируют идентичный дефект: компонент camel-azure-storage-datalake может загрузить файл ADLS Gen2 в локальную файловую систему через операцию downloadToFile, записывая его в каталог, заданный опцией fileDir.
DataLakeFileOperations.downloadToFile формировал локальный путь назначения, объединяя fileDir с именем удалённого пути в том виде, в котором его передавал Azure SDK (new File(fileDir, fileClientWrapper.getFileName())), — без лексической нормализации и без проверки того, что итоговое расположение осталось внутри fileDir. Удалённое имя не контролируется маршрутом: потребитель перечисляет содержимое файловой системы (DataLakeConsumer.createBatchExchangesFromPath) и загружает каждую запись. Поэтому имя пути, содержащее сегменты ../, разрешается за пределами fileDir (CWE-22, обход пути → произвольная запись файла).
Примечание о тестовом стенде. API Azure Data Lake Gen2 не реализован ни одним доступным локальным эмулятором: Azurite возвращает HTTP 400 для Gen2-операций
listPathsи файловых операций. Поэтому данные репродукторы запускают точно тот же уязвимый код (DataLakeFileOperations.downloadToFile→new File(fileDir, fileClientWrapper.getFileName())) напрямую, передавая обёртку клиента Data Lake, чейgetFileName()возвращает удалённое имя, — в точности так, как потребитель передаёт имя, прочитанное изPathItem.getName(). Родственный компонентcamel-azure-storage-blobзакрыт тем же исправлением (CVE-2026-66906), и там идентичный дефект воспроизводится сквозным образом против работающего эмулятора Azurite.
cd camel-spring-boot # or: cd camel-quarkus
mvn clean package
docker compose up -d --build
curl -s http://localhost:8080/exploit/attack
docker compose down
Ожидаемый вывод на затронутой сборке (оба варианта):
2) Download of a file named '../../../../../../tmp/pwned-60093.txt':
resolved local target: /app/downloads/../../../../../../tmp/pwned-60093.txt
File written OUTSIDE it, at /tmp/pwned-60093.txt: true
content: PWNED via path traversal — CVE-2026-60093
>>> PROVEN: DataLakeFileOperations.downloadToFile built the local target as new File(fileDir, fileName) ... : true
| Свойство | Значение |
|---|---|
| Компонент | camel-azure-storage-datalake (Spring Boot: camel-azure-storage-datalake-starter; Quarkus: camel-quarkus-azure-storage-datalake) |
| CWE | CWE-22 (Некорректное ограничение имени пути заданным каталогом — обход пути) |
| Вектор атаки | Файл Gen2, имя пути которого содержит сегменты ../, загружаемый потребителем с заданной опцией fileDir |
| Воздействие | Произвольная запись файла за пределами настроенного каталога fileDir |
| Затронутые версии | С 4.0.0 до 4.14.9, с 4.15.0 до 4.18.4, с 4.19.0 до 4.22.0 |
| Исправленные версии | 4.14.9, 4.18.4, 4.22.0 |
| JIRA | CAMEL-23942 |
| Автор | n0mi1k; Hiep Nguyen |
Теперь потребитель вычисляет путь назначения загрузки и ограничивает его настроенным каталогом fileDir (через AzureFileNameHelper.resolveWithinDirectory), отклоняя имена путей, ведущие за его пределы, — то же исправление, которое охватывает camel-azure-storage-blob (CVE-2026-66906).
Этот репозиторий опубликован в образовательных и защитных целях: помочь пользователям Apache Camel понять уязвимость, проверить, затронуты ли они, и убедиться, что обновление устраняет проблему. Записываемый файл — безвредная метка в каталоге /tmp. Не используйте этот материал против систем, которыми вы не владеете и которые не эксплуатируете.