
Prova de conceito executável que reproduz a CVE-2026-84178, um CSRF de login no callback do fluxo de código de autorização do camel-oauth do Apache Camel, que resgata códigos sem verificar o state.
state)Reprodutor de prova de conceito executável para a vulnerabilidade do Apache Camel em que o callback do authorization-code OAuth
não carregava um parâmetro state que o vinculasse à requisição de autorização que iniciou o fluxo, e não verificava
nenhum. Um authorization code obtido em qualquer navegador podia, portanto, ser resgatado no callback e associado
à sessão que o apresentasse — cross-site request forgery de login: a vítima é silenciosamente autenticada como uma
identidade controlada pelo atacante, de modo que as ações e os dados subsequentes da vítima acabam na conta do atacante. (O
mesmo callback não validado também permitia influenciar o destino de redirecionamento pós-autenticação — um open redirect.)
Como observa o advisory, a verificação de state ocorre antes do resgate do code, portanto a diferença é alcançável sem
qualquer interação com o provedor de identidade.
| Runtime | Diretório | Stack |
|---|---|---|
| Camel Spring Boot | camel-spring-boot/ | Spring Boot 3.5.13 + camel-oauth 4.22.0 (afetado; corrigido em 4.22.1), callback via camel-undertow |
| Camel Quarkus | camel-quarkus/ | Quarkus 3.39.0 + camel-quarkus-oauth 3.39.0 (Camel 4.22.0, afetado; controle corrigido 3.40.0 / Camel 4.22.1), callback via camel-quarkus-platform-http |
Ambos os módulos demonstram o comportamento afetado e o corrigido.
O processador real e não modificado OAuthCodeFlowCallback trata o endpoint de callback. Um pequeno stub OAuth é
registrado no registry do Camel para que o callback seja executado sem um provedor de identidade ativo — ele substitui
apenas o IdP e registra quando um authorization code é resgatado (o que, no fluxo real, vincula a identidade resultante à
sessão que o apresenta). O atacante simplesmente acessa o callback com um code e sem state correspondente:
state
correspondente à requisição de autorização que esta sessão iniciou) — o code nunca é resgatado.cd camel-spring-boot
mvn clean package
docker compose up -d --build
curl -s http://localhost:8080/exploit/attack
docker compose down
Saída esperada na build afetada:
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.
| Propriedade | Valor |
|---|---|
| Componente | camel-oauth (callback do authorization-code, OAuthCodeFlowCallback) |
| CWE | CWE-352 (Cross-Site Request Forgery) |
| Severidade | MÉDIA |
| Vetor de ataque | Uma requisição de callback carregando um authorization code sem state vinculado à requisição de autorização da sessão |
| Impacto | Login CSRF (vítima autenticada como uma identidade controlada pelo atacante); open redirect a partir de uma origem confiável |
| Versões Afetadas | Da 4.11.0 anterior à 4.18.5, da 4.19.0 anterior à 4.22.1 |
| Versões Corrigidas | 4.18.5, 4.22.1, 4.23.0 |
| JIRA | CAMEL-24437 |
| Crédito | Claude Security Scan Tool |
Advisory: https://camel.apache.org/security/CVE-2026-84178.html
O callback agora carrega e verifica um parâmetro state de uso único vinculado à requisição de autorização que a sessão
iniciou: expectedState = session.removeValue(OAUTH_STATE), comparado (em tempo constante) ao parâmetro de consulta
state. Se nenhum fluxo estiver em andamento, ou se o state não corresponder, o callback rejeita a requisição antes
de resgatar o code.
Coloque o callback atrás de um componente que imponha uma vinculação de state de CSRF, ou não dependa do callback do
fluxo de código OAuth para estabelecimento de sessão, até que você possa atualizar.
Este repositório é publicado para fins educacionais e defensivos: para ajudar usuários do Apache Camel a entender a vulnerabilidade, verificar se são afetados e confirmar que a atualização a resolve. O provedor de identidade stub e o "código do atacante" são fixtures locais inertes. Não use este material contra sistemas que você não possui ou opera.