
CVE-2026-84178에 대한 실행 가능한 개념 증명(PoC) 재현기로, Apache Camel camel-oauth의 인증 코드 콜백에서 state를 검증하지 않고 코드를 교환하는 로그인 CSRF 취약점입니다.
state 누락)OAuth authorization-code 콜백이 흐름을 시작한 authorization 요청에 이를 바인딩하는 state 파라미터를 전달하지 않았고, 이를 검증하지도 않았던 Apache Camel 취약점에 대한 실행 가능한 proof-of-concept 재현기입니다. 따라서 어떤 브라우저에서든 획득한 authorization code를 콜백에서 교환(redeem)하여 이를 제시한 세션과 연결할 수 있었습니다 — 로그인 cross-site request forgery: 피해자가 공격자가 제어하는 신원으로 조용히 로그인되어, 피해자의 이후 행동과 데이터가 공격자의 계정에 귀속됩니다. (동일한 미검증 콜백은 인증 후 리다이렉트 대상을 조작할 수도 있었습니다 — open redirect.) 권고문에서 언급하듯이, state 검사는 코드가 교환되기 전에 실행되므로, 이 차이는 identity provider와의 어떤 상호작용 없이도 도달 가능합니다.
| 런타임 | 디렉터리 | 스택 |
|---|---|---|
| Camel Spring Boot | camel-spring-boot/ | Spring Boot 3.5.13 + camel-oauth 4.22.0 (영향받음; 4.22.1에서 수정), 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), camel-quarkus-platform-http를 통한 콜백 |
두 모듈 모두 영향받는 동작 및 수정된 동작을 보여줍니다.
실제로 수정되지 않은 OAuthCodeFlowCallback 프로세서가 콜백 엔드포인트를 처리합니다. 작은 스텁 OAuth 가 Camel 레지스트리에 등록되어 콜백이 실제 identity provider 없이 실행됩니다 — 이는 오직 IdP를 대신하며, authorization code가 교환되는 시점을 기록합니다(실제 흐름에서는 이때 결과 신원이 제시하는 세션에 바인딩됩니다). 공격자는 단순히 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 없이 인가 코드를 전달하는 콜백 요청 |
| 영향 | 로그인 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 쿼리 매개변수와 (상수 시간으로) 비교합니다.
진행 중인 흐름이 없거나 state가 일치하지 않으면, 콜백은 코드를 교환하기 전에 요청을 거부합니다.
업그레이드가 가능해질 때까지 콜백을 CSRF state 바인딩을 강제하는 구성 요소 뒤에 배치하거나, 세션 설정을 위해
OAuth 코드 흐름 콜백에 의존하지 마십시오.
이 저장소는 교육 및 방어 목적으로 게시되었습니다: Apache Camel 사용자가 취약점을 이해하고, 영향을 받는지 확인하고, 업그레이드가 이를 해결하는지 확인할 수 있도록 돕기 위함입니다. 스텁 신원 제공자와 "공격자 코드"는 동작하지 않는 로컬 픽스처입니다. 소유하거나 운영하지 않는 시스템에 이 자료를 사용하지 마십시오.