
CVE-2026-85315에 대한 실행 가능한 개념 증명 재현기로, Camel Spring Boot 및 Quarkus에서 camel-grpc 컨슈머 예외 메시지 노출(CWE-209)을 시연합니다.
gRPC 컨슈머 뒤의 라우트가 실패했을 때 라우트 예외의 메시지가 gRPC Status description에 복사되는 Apache Camel 취약점에 대한 실행 가능한 개념 증명(PoC) 재현기입니다. 서버에만 국한되는 상태 cause(withCause(...))와 달리, description은 호출 클라이언트로 전송되므로, 실패를 유발할 수 있는 외부 호출자가 내부 오류 메시지를 읽을 수 있었습니다. 실제로는 예외 메시지에 담긴 클래스 및 패키지 이름, 파일 경로, 호스트 이름, 연결 세부 정보 등이 해당됩니다(CWE-209). 이는 함께 발표된 knative, mina, CXF 권고와 같은 계열의, 억제되지 않은 컨슈머 예외 문제 중 gRPC에 해당하는 사례입니다.
| 런타임 | 디렉터리 | 스택 |
|---|---|---|
| Camel Spring Boot | camel-spring-boot/ | Spring Boot 3.5.13 + camel-grpc 4.22.0 (영향받음; 수정 버전 4.22.1) |
| Camel Quarkus | camel-quarkus/ | Quarkus 3.39.0 + camel-quarkus-grpc (Camel 4.22.0, 영향받음; 수정 대조군 CQ 3.40.0 / Camel 4.22.1) |
두 모듈 모두 실제 camel-grpc 컨슈머를 대상으로 영향받는 동작 및 수정된 동작을 보여줍니다.
각 모듈은 라우트가 항상 내부 정보처럼 보이는 메시지와 함께 실패하는 camel-grpc 컨슈머(camel-grpc 자체 테스트 proto의 PingPong 서비스)를 실행합니다:
Internal failure contacting jdbc:postgresql://db.internal.local:5432 (user=svc_admin) [CVE-2026-85315]
검증기 엔드포인트 /exploit/attack은 외부 gRPC 클라이언트 역할을 합니다. 즉, PingSyncSync를 호출하고 StatusRuntimeException을 잡아서 서버가 반환한 Status 코드와 설명을 보고합니다.
muteException 컨슈머 옵션이 기본값 true이므로, 설명은 일반적인 "Exchange processing failed"가 되고 실제 메시지는 서버를 떠나지 않습니다(로컬 전용 상태 원인에만 보관됨).# Camel Spring Boot
cd camel-spring-boot
mvn clean package
docker compose up -d --build
curl -s http://localhost:8080/exploit/attack # affected: description leaks the internal message; >>> PROVEN
docker compose down
# Patched control
mvn clean package -Dcamel.version=4.22.1
java -jar target/cve-2026-85315-grpc-exception-disclosure-0.0.1-SNAPSHOT.jar &
curl -s http://localhost:8080/exploit/attack # fixed: description is "Exchange processing failed"; >>> 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): description leaks the internal message
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: description is "Exchange processing failed"
각 모듈은 동일한 프로세스 내에서 8080 포트의 검증기(verifier)에 서비스를 제공하고 50051 포트에서 camel-grpc 컨슈머를 실행하며, 8080 포트만 외부에 게시됩니다.
| 속성 | 값 |
|---|---|
| 구성 요소 | camel-grpc (GrpcMethodHandler, 컨슈머) |
| CWE | CWE-209 (민감한 정보를 포함하는 오류 메시지 생성) |
| 심각도 | MEDIUM |
| 공격 벡터 | 외부 gRPC 클라이언트가 라우트 실패를 유발하고 전송된 Status 설명을 읽음 |
| 영향 | 내부 오류 세부 정보(클래스/패키지 이름, 경로, 호스트 이름, 연결 세부 정보)가 호출자에게 노출됨 |
| 영향받는 버전 | 4.0.0부터 4.18.5 이전, 4.19.0부터 4.22.1 이전 |
| 수정된 버전 | 4.18.5, 4.22.1, 4.23.0 |
| JIRA | CAMEL-24478 |
| 크레딧 | Claude Security Scan Tool |
권고문: https://camel.apache.org/security/CVE-2026-85315.html
Quarkus 영향받는 모듈은 CQ 3.39.0(Camel 4.22.0) 기반으로 빌드되었습니다. 패치된 제어 버전은 CQ 3.40.0(Camel 4.22.1)입니다.
GrpcMethodHandler는 muteException 컨슈머 옵션(기본값
true)을 추가합니다. 활성화되면 실패한 교환은 전송된 상태에서 일반적인 설명 "Exchange processing failed"를
생성하며, 라우트 예외는 여전히 withCause(...)를 통해 로컬에 첨부되는데, 이는 gRPC가 클라이언트에 전송하지
않습니다. 이전 동작을 복원하려면 엔드포인트에서 muteException=false로 설정하십시오.
onException 핸들러에서 실패를 명시적인 상태로 매핑하여 프레임워크가 예외 메시지를 설명에 복사하지 않도록
하십시오.
이 저장소는 교육 및 방어 목적으로 게시됩니다: Apache Camel 사용자가 취약점을 이해하고, 영향을 받는지 확인하며,
업그레이드가 문제를 해결하는지 확인할 수 있도록 돕기 위해서입니다. "내부" 메시지는 무해한 자리 표시자
(db.internal.local, svc_admin)이며 전체 데모는 단일 프로세스에서 실행됩니다. 소유하거나 운영하지 않는
시스템에 이 자료를 사용하지 마십시오.