
Рабочий воспроизводитель proof-of-concept для CVE-2026-84178 — CSRF-уязвимости при входе в callback авторизационного кода Apache Camel camel-oauth, который обменивает коды без проверки state.
state)Запускаемый воспроизводитель proof-of-concept для уязвимости Apache Camel, при которой callback OAuth authorization-code
не содержал параметра state, привязывающего его к запросу авторизации, инициировавшему поток, и не проверял
его. Полученный в любом браузере authorization code мог быть погашен на callback и связан с той сессией, которая
его предъявила — межсайтовая подделка запроса при входе: жертва незаметно входит под учётной записью, контролируемой
атакующим, поэтому последующие действия и данные жертвы попадают в аккаунт атакующего. (Тот же непроверяемый callback
также позволял влиять на цель перенаправления после аутентификации — открытый редирект.)
Как отмечается в рекомендации, проверка state выполняется до погашения кода, поэтому разница достижима без
какого-либо взаимодействия с провайдером идентификации.
| Среда выполнения | Каталог | Стек |
|---|---|---|
| Camel Spring Boot | camel-spring-boot/ | Spring Boot 3.5.13 + camel-oauth 4.22.0 (уязвим; исправлено в 4.22.1), callback через camel-undertow |
| Camel Quarkus | camel-quarkus/ | Quarkus 3.39.0 + camel-quarkus-oauth 3.39.0 (Camel 4.22.0, уязвим; исправлено в контрольной версии 3.40.0 / Camel 4.22.1), callback через camel-quarkus-platform-http |
Оба модуля демонстрируют как уязвимое, так и исправленное поведение.
Реальный, немодифицированный процессор OAuthCodeFlowCallback обрабатывает endpoint callback. В реестре Camel
регистрируется крошечный заглушечный OAuth, чтобы callback работал без живого провайдера идентификации — он
заменяет только IdP и фиксирует момент погашения authorization code (что в реальном потоке привязывает результирующую
идентичность к предъявляющей сессии). Атакующий просто обращается к callback с code и без соответствующего state:
state,
соответствующий запросу авторизации, инициированному этой сессией) — код никогда не погашается.cd camel-spring-boot
mvn clean package
docker compose up -d --build
curl -s http://localhost:8080/exploit/attack
docker compose down
Ожидаемый вывод на затронутой сборке:
Request: GET /callback?code=ATTACKER-SUPPLIED-AUTH-CODE (no 'state' parameter)
Callback HTTP status: 302
>>> PROVEN: the callback redeemed the authorization code ... WITHOUT verifying a state parameter ... login CSRF.
| Свойство | Значение |
|---|---|
| Компонент | camel-oauth (обратный вызов authorization-code, OAuthCodeFlowCallback) |
| CWE | CWE-352 (межсайтовая подделка запроса) |
| Уровень серьёзности | MEDIUM |
| Вектор атаки | Запрос обратного вызова, несущий код авторизации без state, привязанного к запросу авторизации сессии |
| Воздействие | Login CSRF (жертва входит под идентичностью, контролируемой атакующим); открытый редирект с доверенного источника |
| Затронутые версии | С 4.11.0 до 4.18.5, с 4.19.0 до 4.22.1 |
| Исправленные версии | 4.18.5, 4.22.1, 4.23.0 |
| JIRA | CAMEL-24437 |
| Благодарность | Claude Security Scan Tool |
Рекомендация: https://camel.apache.org/security/CVE-2026-84178.html
Теперь обратный вызов несёт и проверяет одноразовый параметр state, привязанный к запросу авторизации, который
запустила сессия: expectedState = session.removeValue(OAUTH_STATE), сравниваемый (за постоянное время) с параметром
запроса state. Если никакой поток не выполняется или состояние не совпадает, обратный вызов отклоняет запрос до
обмена кода.
Разместите обратный вызов за компонентом, который обеспечивает привязку CSRF state, или не полагайтесь на обратный
вызов OAuth code-flow для установления сессии, пока не сможете обновиться.
Этот репозиторий публикуется в образовательных и защитных целях: чтобы помочь пользователям Apache Camel понять уязвимость, проверить, затронуты ли они, и убедиться, что обновление её устраняет. Заглушка провайдера идентификации и «код атакующего» являются инертными локальными фикстурами. Не используйте этот материал против систем, которыми вы не владеете и которые не эксплуатируете.