
CVE-2026-91858에 대한 실행 가능한 Spring Boot 및 Quarkus 재현 프로그램으로, 서드파티 TransformerFactory를 통한 Apache Camel camel-fop의 XXE 취약점이며, 취약 버전과 패치 버전 검증을 포함합니다.
Apache Camel 취약점에 대한 실행 가능한 개념 증명(PoC) 재현기입니다. 이 취약점은 camel-fop의 FopProducer가 XSL-FO 메시지 본문에 대해 identity 변환을 실행하기 전에 javax.xml.transform.TransformerFactory를 FEATURE_SECURE_PROCESSING만으로 생성했던 문제입니다. JDK 내장 트랜스포머에서는 해당 기능만으로도 이미 accessExternalDTD/accessExternalStylesheet 제한이 비워지므로 외부 리소스가 거부됩니다. 하지만 Saxon-HE와 같은 서드파티 JAXP TransformerFactory가 클래스패스에 있는 경우 — 예를 들어 애플리케이션이 camel-xslt-saxon이나 camel-saxon도 사용하는 경우 — TransformerFactory.newInstance()는 해당 구현을 반환하며, FEATURE_SECURE_PROCESSING만으로는 그 구현에서 외부 리소스 접근을 제한하지 않습니다. 그러면 XSL-FO 본문에 선언된 외부 서브셋을 가진 DOCTYPE이 본문 변환 중에 해석되므로, 외부 발신자의 문서가 Camel 프로세스가 읽을 수 있는 파일을 읽거나 프로세스가 지정한 호스트로 요청을 보내도록 만들 수 있습니다(CWE-611).
| 런타임 | 디렉터리 | 스택 |
|---|---|---|
| Camel Spring Boot | camel-spring-boot/ | Spring Boot 3.5.13 + camel-fop 4.22.0 (영향받음; 4.22.1에서 수정) + Saxon-HE 13.0 |
| Camel Quarkus | camel-quarkus/ | Quarkus 3.39.0 + camel-quarkus-fop (Camel 4.22.0, 영향받음; 수정된 대조군 CQ 3.40.0 / Camel 4.22.1) + Saxon-HE 13.0 |
두 모듈 모두 실제 FopProducer를 대상으로 영향받는 동작 및 수정된 동작을 보여줍니다. 두 모듈 모두 Saxon-HE가 클래스패스에 있습니다 — 이것이 결함의 전제 조건입니다. JDK 트랜스포머를 사용하는 기본 배포는 수정 전후 모두 영향을 받지 않습니다.
검증 엔드포인트 /exploit/attack은 인프로세스 HTTP 콜백을 시작하고, 해당 콜백을 가리키는 외부 DTD를 DOCTYPE에 선언한 XSL-FO 문서를 fop:pdf로 전송합니다:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE fo:root SYSTEM "http://localhost:<port>/external.dtd">
<fo:root …>…Hello…</fo:root>
오라클은 단순히 콜백이 요청되었는지 여부입니다 — 외부 리소스가 실제로 가져와졌다는 결정적 증거입니다:
TransformerFactory.newInstance()가 Saxon을 반환하며, 보안 처리만 적용된 상태에서도 여전히 외부 DTD를 가져옵니다 — 콜백이 발생합니다(동일한 메커니즘이 file:// URL을 읽습니다).ACCESS_EXTERNAL_DTD가 ""로 설정되어 Saxon이 외부 DTD를 거부합니다; 콜백이 발생하지 않습니다.# Camel Spring Boot
cd camel-spring-boot
mvn clean package
docker compose up -d --build
curl -s http://localhost:8080/exploit/attack # affected: callback hit = true; >>> PROVEN
docker compose down
# Patched control
mvn clean package -Dcamel.version=4.22.1
java -Djava.awt.headless=true -jar target/cve-2026-91858-fop-xxe-0.0.1-SNAPSHOT.jar &
curl -s http://localhost:8080/exploit/attack # fixed: callback hit = false; >>> 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): callback hit = true
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 -Djava.awt.headless=true -jar target/quarkus-app/quarkus-run.jar &
curl -s http://localhost:8080/exploit/attack # fixed: callback hit = false
| 속성 | 값 |
|---|---|
| 구성 요소 | camel-fop (FopProducer) |
| CWE | CWE-611 (XML 외부 엔티티 참조의 부적절한 제한) |
| 심각도 | MEDIUM |
| 공격 벡터 | 외부 발신자의 XSL-FO가 fop: 프로듀서에 도달하며, 해당 배포 환경의 클래스패스에 타사 JAXP TransformerFactory(예: Saxon-HE)가 함께 존재하는 경우 |
| 영향 | Camel 프로세스가 읽을 수 있는 로컬 파일 읽기, 문서에 명시된 내부 호스트로의 SSRF |
| 영향받는 버전 | 4.0.0부터 4.18.5 이전, 4.19.0부터 4.22.1 이전 (JDK가 아닌 TransformerFactory가 존재하는 경우에만) |
| 수정된 버전 | 4.18.5, 4.22.1, 4.23.0 |
| JIRA | CAMEL-24605 |
| 크레딧 | Claude Security Scan Tool |
권고문: https://camel.apache.org/security/CVE-2026-91858.html
Quarkus 영향받는 모듈은 CQ 3.39.0 (Camel 4.22.0)을 기반으로 빌드되었습니다. 패치된 제어는 CQ 3.40.0 (Camel 4.22.1)입니다. Saxon-HE 13.0이 두 모듈 모두에 추가되어, camel-xslt-saxon/camel-saxon을 함께 사용하는 애플리케이션을 대표합니다; JDK가 아닌 TransformerFactory가 없으면 이 결함은 도달할 수 없습니다.
FopProducer는 이제 생성하는 TransformerFactory에 FEATURE_SECURE_PROCESSING에 더하여
XMLConstants.ACCESS_EXTERNAL_DTD와 XMLConstants.ACCESS_EXTERNAL_STYLESHEET도 빈 문자열로 설정하며,
이는 XmlConverter에서 사용하는 보안 XML 처리 구성과 일치합니다. 따라서 해당 속성을 준수하는 모든 JAXP 구현(Saxon-HE 포함)에서
외부 DTD 및 스타일시트 접근이 거부됩니다.
신뢰할 수 없는 XSL-FO를 fop: 프로듀서로 전송하지 않거나, 대체 JAXP TransformerFactory(예: Saxon-HE)를 클래스패스에서 제거하여
보안 처리 하에서 이미 외부 DTD를 거부하는 JDK 트랜스포머가 사용되도록 하십시오.
이 저장소는 교육 및 방어 목적으로 게시됩니다: Apache Camel 사용자가 취약점을 이해하고, 영향을 받는지 확인하며, 업그레이드로 문제가 해결되는지 검증할 수 있도록 돕기 위함입니다. 외부 DTD는 localhost의 인프로세스 콜백을 가리키며, 재현기 외부의 어떤 것도 접촉하지 않고 민감한 파일도 읽지 않습니다. 소유하거나 운영하지 않는 시스템에 이 자료를 사용하지 마십시오.