
Runnable proof-of-concept reproducer for CVE-2026-84178, a login CSRF in Apache Camel camel-oauth's authorization-code callback that redeems codes without verifying state.
state)Runnable proof-of-concept reproducer for the Apache Camel vulnerability where the OAuth authorization-code callback
did not carry a state parameter binding it to the authorization request that started the flow, and did not verify
one. An authorization code obtained in any browser could therefore be redeemed at the callback and associated
with whichever session presented it — login cross-site request forgery: a victim is silently signed in as an
identity the attacker controls, so the victim's subsequent actions and data land in the attacker's account. (The
same unvalidated callback also allowed the post-authentication redirect target to be influenced — an open redirect.)
As the advisory notes, the state check runs before the code is redeemed, so the difference is reachable without
any interaction with the identity provider.
| Runtime | Directory | Stack |
|---|---|---|
| Camel Spring Boot | camel-spring-boot/ | Spring Boot 3.5.13 + camel-oauth 4.22.0 (affected; fixed 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, affected; fixed control 3.40.0 / Camel 4.22.1), callback via camel-quarkus-platform-http |
Both modules demonstrate the affected and the fixed behaviour.
The real, unmodified OAuthCodeFlowCallback processor handles the callback endpoint. A tiny stub OAuth is
registered in the Camel registry so the callback runs without a live identity provider — it stands in only for the
IdP, and records when an authorization code is redeemed (which, in the real flow, binds the resulting identity to the
presenting session). The attacker simply hits the callback with a code and no matching state:
state
matching the authorization request this session started) — the code is never redeemed.cd camel-spring-boot
mvn clean package
docker compose up -d --build
curl -s http://localhost:8080/exploit/attack
docker compose down
Expected output on the affected build:
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.
| Property | Value |
|---|---|
| Component | camel-oauth (authorization-code callback, OAuthCodeFlowCallback) |
| CWE | CWE-352 (Cross-Site Request Forgery) |
| Severity | MEDIUM |
| Attack vector | A callback request carrying an authorization code with no state bound to the session's authorization request |
| Impact | Login CSRF (victim signed in as an attacker-controlled identity); open redirect from a trusted origin |
| Affected Versions | From 4.11.0 before 4.18.5, from 4.19.0 before 4.22.1 |
| Fixed Versions | 4.18.5, 4.22.1, 4.23.0 |
| JIRA | CAMEL-24437 |
| Credit | Claude Security Scan Tool |
Advisory: https://camel.apache.org/security/CVE-2026-84178.html
The callback now carries and verifies a single-use state parameter bound to the authorization request the session
started: expectedState = session.removeValue(OAUTH_STATE), compared (constant-time) to the state query
parameter. If no flow is in progress, or the state does not match, the callback rejects the request before
redeeming the code.
Place the callback behind a component that enforces a CSRF state binding, or do not rely on the OAuth code-flow
callback for session establishment, until you can upgrade.
This repository is published for educational and defensive purposes: to help Apache Camel users understand the vulnerability, verify whether they are affected, and confirm that upgrading resolves it. The stub identity provider and the "attacker code" are inert local fixtures. Do not use this material against systems you do not own or operate.