
Рабочий воспроизводитель на Spring Boot и Quarkus для CVE-2026-85248 — состояние гонки при параллельной работе с Signature в camel-pqc, приводящее к обходу проверки подписи ML-DSA, с уязвимой и исправленной сборками.
Signature (обход проверки подписи)Запускаемый воспроизводитель proof-of-concept для уязвимости Apache Camel, при которой PQC-продюсер удерживал единственный
экземпляр java.security.Signature и использовал его для каждого обмена без синхронизации. Signature является stateful
и не потокобезопасным: update() накапливает данные для подписи или проверки, а verify()/sign() потребляют это
накопленное состояние. При конкурентных обменах, разделяющих один экземпляр, вызовы update и verify разных сообщений
перемешиваются, поэтому проверка может завершиться для данных, принадлежащих другому обмену, или для частично
накопленного буфера. Результат недетерминирован и включает случай, когда проверка сообщает об успехе для сообщения,
подпись которого фактически не проверялась, что подрывает гарантию, ради которой существует компонент. Для этого
достаточно лишь конкурентного трафика через одну и ту же конечную точку — обычное условие для маршрута Camel под нагрузкой.
| Среда выполнения | Каталог | Стек |
|---|---|---|
| Camel Spring Boot | camel-spring-boot/ | Spring Boot 3.5.13 + camel-pqc 4.22.0 (уязвим; исправлено в 4.22.1) |
| Camel Quarkus | camel-quarkus/ | Quarkus 3.39.0 + camel-quarkus-pqc (Camel 4.22.0, уязвим; исправленный контроль CQ 3.40.0 / Camel 4.22.1) |
Оба модуля демонстрируют как уязвимое, так и исправленное поведение.
Маршрут подписывает каждое сообщение постквантовым ключом ML-DSA, а затем немедленно проверяет только что
созданную подпись, поэтому каждое легитимно подписанное сообщение должно проходить проверку с результатом true. Драйвер выполняет 1024 таких цикла sign→verify
конкурентно (16 потоков) через общие продюсеры pqc:.
true — некоторые возвращают false, некоторые вызывают
ошибки механизма подписи — потому что единственный stateful Signature, разделяемый конкурентными обменами, повреждается
из-за перемешивания. Вердикт больше не соответствует сообщению, для которого он был вычислен. (Та же гонка в опасном
направлении позволяет verify() завершиться успешно для данных, которые он никогда не покрывал.)Signature.# Camel Spring Boot
cd camel-spring-boot
mvn clean package
docker compose up -d --build
curl -s http://localhost:8080/exploit/attack # affected: many of 1024 broken; >>> PROVEN
docker compose down
# Patched control
mvn clean package -Dcamel.version=4.22.1
java -jar target/cve-2026-85248-pqc-signature-race-0.0.1-SNAPSHOT.jar &
curl -s http://localhost:8080/exploit/attack # fixed: 0 broken; >>> Not exploited
# Camel Quarkus
cd camel-quarkus
mvn clean package
docker compose up -d --build
curl -s http://localhost:8080/exploit/attack # affected (Camel 4.22.0): many broken
docker compose down
# Patched control: CQ 3.40.0 ships Camel 4.22.1
mvn clean package -Dcamel-quarkus.version=3.40.0 -Dquarkus.platform.version=3.40.0
java -jar target/quarkus-app/quarkus-run.jar &
curl -s http://localhost:8080/exploit/attack # fixed: 0 broken
Гонка по своей природе зависит от таймингов; репродьюсер создаёт достаточную конкурентность (1024 round-trip), чтобы она надёжно проявлялась на уязвимой сборке. Если уязвимый запуск когда-либо покажет 0 broken, запустите его повторно.
| Свойство | Значение |
|---|---|
| Компонент | camel-pqc (подпись/проверка PQCProducer) |
| CWE | CWE-362 (Конкурентное выполнение с использованием общего ресурса при ненадлежащей синхронизации) |
| Критичность | MEDIUM |
| Вектор атаки | Конкурентный трафик через одну и ту же конечную точку pqc:, использующий один общий stateful-объект java.security.Signature |
| Воздействие | Недетерминированная проверка подписи; проверка может сообщить об успехе для сообщения, подпись которого фактически не проверялась |
| Уязвимые версии | С 4.12.0 до 4.18.5, с 4.19.0 до 4.22.1 |
| Исправленные версии | 4.18.5, 4.22.1, 4.23.0 |
| JIRA | CAMEL-24445 |
| Благодарность | Claude Security Scan Tool |
Рекомендация: https://camel.apache.org/security/CVE-2026-85248.html
PQCProducer больше не разделяет Signature между конкурентными
обменами. Когда producer сам создавал экземпляр, теперь он создаёт новый экземпляр для каждого обмена
(signerForExchange()); когда пользователь настроил экземпляр (JVM-wide public static final), доступ к нему
synchronized. В любом случае никакие два обмена не чередуют свои последовательности init/update/verify на одном экземпляре.
Ограничьте уязвимый маршрут одним конкурентным потребителем, чтобы никакие два обмена не использовали экземпляр Signature
одновременно.
Этот репозиторий публикуется в образовательных и защитных целях: чтобы помочь пользователям Apache Camel понять уязвимость, проверить, затронуты ли они, и убедиться, что обновление её устраняет. Сообщения и ключи — это инертные локальные фикстуры. Не используйте этот материал против систем, которыми вы не владеете и не управляете.