
Docker 기본 이미지로, CVE-2025-12543에 대한 Host 헤더 검증 수정이 Undertow 1.4.x에 백포트되어 WildFly 11 애플리케이션의 안전한 배포를 가능하게 합니다.
이 저장소는 CVE-2025-12543(Undertow의 치명적인 Host 헤더 검증 취약점)에 대한 백포트 수정 사항이 포함된 WildFly 11.0.0.Final 기반의 Docker 기본 이미지를 제공합니다.
이 이미지는 동료들에게 기본 이미지로 제공하기 위해 제작되었습니다. 동료들은 자체 .war 애플리케이션과 standalone.xml을 이 이미지 위에 배포할 수 있습니다.
| 필드 | 세부 정보 |
|---|---|
| CVE ID | CVE-2025-12543 |
| 구성 요소 | io.undertow:undertow-core |
| 심각도 | 치명적(CVSS 9.6) |
| 영향을 받는 버전 | < 2.2.39의 모든 버전(1.4.x 포함) |
| 수정 버전 | Undertow 2.2.39 / 2.3.22 |
| WildFly 11 버전 | undertow-core-1.4.18.Final — 영향 있음 |
Undertow가 들어오는 HTTP 요청에서 Host 헤더를 제대로 검증하지 못합니다. 잘못된 형식이나 악의적인 Host 헤더가 포함된 요청이 거부되지 않고 처리되어 다음이 가능해집니다:
다른 사용자들이 여전히 WildFly 11을 사용하고 있으며, 업그레이드할 자원이나 계획이 현재 없습니다. 대신 수정 사항을 Undertow 1.4.18.Final JAR에 직접 백포트했습니다.
.
├── Dockerfile # 메인 이미지 정의
├── README.md
├── wildfly-dist-11.0.0.Final.tar.gz # WildFly 11 배포 아카이브
├── reports/
│ ├── result-20260401-0230.txt # 취약점을 식별한 CVE 스캔 보고서
│ └── wildfly_11.0.0.Final_*.txt # 추가 스캔 보고서
└── patch/
├── src/
│ ├── HostHeaderHandler.java # 백포트된 수정 사항 — 새로운 핸들러 클래스
│ ├── HttpReadListener_only.java # 디컴파일 + 패치된 HttpReadListener 소스(참조)
│ └── PatchHttpReadListener.java # Javassist 바이트코드 패처 도구
├── build.sh # 빌드 스크립트 — 패치된 JAR를 처음부터 다시 빌드
├── undertow-core-1.4.18.Final.jar # 원본(미패치) JAR — 참조용으로 보관
└── undertow-core-1.4.18.Final-patched.jar # 이미지에 주입되는 패치된 JAR
Dockerfile최종 이미지를 빌드합니다. 다음을 수행합니다:
bitnamilegacy/java:1.8.432-7-debian-12-r2(OpenJDK 1.8.0_432)를 기본 이미지로 사용/opt/jboss/wildfly에 압축 해제undertow-core-1.4.18.Final.jar를 패치된 버전으로 교체standalone.sh -b 0.0.0.0으로 WildFly 시작(모든 인터페이스에 바인딩)patch/undertow-core-1.4.18.Final-patched.jar패치된 Undertow JAR입니다. 다음 두 가지 변경 사항을 제외하고는 원본과 동일합니다:
io/undertow/server/handlers/HostHeaderHandler.class(및 내부 클래스)io/undertow/server/protocol/http/HttpReadListener.class — 요청 파이프라인에 HostHeaderHandler 주입patch/src/HostHeaderHandler.java백포트된 Host 헤더 검증 핸들러입니다. Undertow PR #1857 (UNDERTOW-2656)에서 포팅되었습니다.
모든 상수(IP4_EXACT, IP6_EXACT, 문자 테이블)는 자체 포함되어 있습니다 — Undertow 2.x에서 추가된 API에 의존하지 않습니다. 모든 HTTP 요청마다 다음을 검증합니다:
400 Bad Request 반환patch/src/PatchHttpReadListener.java일회성 Javassist 바이트코드 패처입니다. 원본 JAR에서 HttpReadListener를 로드하고 다음을 대체합니다:
// 이전
Connectors.executeRootHandler(connection.getRootHandler(), exchange);
// 이후
Connectors.executeRootHandler(
HostHeaderHandler.WRAPPER.wrap(connection.getRootHandler()),
exchange
);
이렇게 하면 HttpReadListener(복잡한 내부 클래스 및 xnio 내부에 의존)를 완전히 재컴파일할 필요 없이 모든 HTTP 요청에 HostHeaderHandler가 자동으로 주입됩니다.
patch/src/HttpReadListener_only.javaUndertow 1.4.18.Final의 원본 HttpReadListener의 디컴파일된 소스로, 주입 지점을 찾기 위한 참조로 사용됩니다. 감사 목적으로 이 소스의 패치된 버전도 함께 보관됩니다.
reports/result-20260401-0230.txtundertow-core-1.4.18.Final에서 CVE-2025-12543을 식별한 CVE 스캔 보고서(2026-04-01 생성)입니다:
/opt/jboss/wildfly/modules/system/layers/base/io/undertow/core/main/undertow-core-1.4.18.Final.jar
스캔 보고서(result-20260401-0230.txt)에서 undertow-core-1.4.18.Final이 CVE-2025-12543(CVSS 9.6)의 영향을 받는 것으로 확인되었습니다.
수정 사항은 Undertow PR #1857에 있으며, main(2026-01-09)에 병합되고 2.2.x 및 2.3.x로 백포트되었습니다. 수정 사항은 HostHeaderHandler.java를 추가하고 이를 HttpReadListener에 연결하여 모든 요청에서 Host 헤더를 검증합니다.
Undertow 1.4.x → 2.2.x는 주 버전 점프로, 호환되지 않는 API 변경이 있습니다. WildFly 11은 JBoss Modules를 통해 Undertow 1.4.x와 강하게 결합되어 있습니다. 직접 JAR를 교체하면 시작 시 ClassNotFoundException/NoSuchMethodError가 발생합니다.
HostHeaderHandler.java 백포트Undertow 1.4.18.Final과 호환되는 자체 포함 버전의 HostHeaderHandler.java를 작성합니다:
IP4_EXACT, IP6_EXACT)를 인라인합니다 — 1.4.x의 NetworkUtils에서는 사용 불가exchange.isHostIncludedInRequestURI() 제거 — 1.4.x의 HttpServerExchange에서는 사용 불가WildFly 이미지 내부의 Undertow 1.4.18 + xnio 클래스패스에 대해 컴파일합니다:
javac -cp undertow-core-1.4.18.Final.jar:xnio-api-3.5.4.Final.jar:jboss-logging-3.3.1.Final.jar \
-d out HostHeaderHandler.java
HttpReadListener 패치Procyon으로 HttpReadListener를 디컴파일하여 주입 지점을 찾습니다:
Connectors.executeRootHandler(this.connection.getRootHandler(), httpServerExchange);
handleEventWithNoRunningRequest()에 위치합니다.
HttpReadListener에는 익명 내부 클래스($1, $2, $3)가 있어 디컴파일된 소스에서 참조할 수 없으므로 완전한 재컴파일은 불가능합니다. 대신 Javassist(PatchHttpReadListener.java)를 사용하여 바이트코드를 직접 조작합니다 — executeRootHandler 호출을 래핑하여 루트 핸들러를 HostHeaderHandler.WRAPPER로 감쌉니다.
java -cp javassist.jar:undertow-core-1.4.18.Final.jar:out \
PatchHttpReadListener undertow-core-1.4.18.Final.jar out/
원본 JAR를 복사하고 패치된/새 클래스 파일을 주입합니다:
cp undertow-core-1.4.18.Final.jar undertow-core-1.4.18.Final-patched.jar
jar uf undertow-core-1.4.18.Final-patched.jar \
-C out io/undertow/server/handlers/HostHeaderHandler.class \
-C out "io/undertow/server/handlers/HostHeaderHandler\$Wrapper.class" \
-C out "io/undertow/server/handlers/HostHeaderHandler\$1.class" \
-C out io/undertow/server/protocol/http/HttpReadListener.class
패치된 JAR를 위한 COPY 명령을 추가하고 이미지 내부에서 원본을 교체합니다:
COPY patch/undertow-core-1.4.18.Final-patched.jar /tmp/
RUN cp /tmp/undertow-core-1.4.18.Final-patched.jar \
/opt/jboss/wildfly/modules/system/layers/base/io/undertow/core/main/undertow-core-1.4.18.Final.jar
docker build -t wildfly:11.0.0.Final-patched .
검증:
# 유효한 Host 헤더 — 200 반환
curl -v -H "Host: localhost:8080" http://localhost:8080/
# Host에 잘못된 문자 — 400 Host Header Bad Characters 반환
curl -v -H "Host: evil<script>" http://localhost:8080/
# 중복 Host 헤더 — 400 Bad Request 반환
# 참고: curl은 내부적으로 Host 헤더를 중복 제거하므로, 이 테스트를 위해 raw TCP 요청이 필요합니다
exec 3<>/dev/tcp/localhost/8080; \
printf "GET / HTTP/1.1\r\nHost: localhost\r\nHost: evil.com\r\nConnection: close\r\n\r\n" >&3; \
sleep 1; head -1 <&3; exec 3>&-
# 포트 범위 초과 — 400 Host Header Malformed Port 반환
curl -v -H "Host: localhost:99999" http://localhost:8080/
Host 헤더가 포함되어야 함이 패치 이전에는 WildFly의 REQUIRE_HOST_HTTP11 옵션이 기본적으로 false로 설정되어 있어, Host 헤더가 없는 HTTP/1.1 요청이 자동으로 수락되었습니다.
이 패치 이후에는 HostHeaderHandler가 RFC 7230을 엄격하게 적용합니다 — REQUIRE_HOST_HTTP11 설정과 관계없이 Host 헤더가 없는 모든 HTTP/1.1 요청은 400 No Host Header로 거부됩니다.
영향을 받을 수 있는 경우:
GET / HTTP/1.1을 보내는 상태 확인 프로브해결 방법:
모든 HTTP/1.1 클라이언트가 Host 헤더를 포함하도록 하십시오. 이는 RFC 7230에서 이미 요구하는 사항이며, 표준 HTTP 라이브러리(curl, Java의 HttpClient 등)는 자동으로 이 작업을 수행합니다. 비준수 또는 매우 오래된 사용자 정의 클라이언트만 영향을 받습니다.
# 이제 이 요청은 400으로 거부됩니다:
GET /health HTTP/1.1
Connection: close
# 올바른 요청이며 정상적으로 작동합니다:
GET /health HTTP/1.1
Host: your-server:8080
Connection: close
새 환경(예: 미리 빌드된 JAR를 사용할 수 없는 경우)에서 patch/undertow-core-1.4.18.Final-patched.jar를 다시 생성해야 하는 경우 제공된 빌드 스크립트를 사용하십시오.
요구 사항: Java 8 JDK, curl, Maven Central 인터넷 접속.
cd patch
bash build.sh
스크립트는 다음을 수행합니다:
HostHeaderHandler.java 컴파일PatchHttpReadListener.java를 컴파일 및 실행하여 Javassist를 통해 HttpReadListener 바이트코드 패치undertow-core-1.4.18.Final-patched.jar로 재패키징완료 후 평소처럼 docker build를 진행하십시오.
참고:
wildfly-dist-11.0.0.Final.tar.gz는 이 저장소에 포함되어 있지 않습니다(GitHub의 100 MB 제한 초과). 빌드 전에 Maven Central에서 다운로드하십시오:https://repo1.maven.org/maven2/org/wildfly/wildfly-dist/11.0.0.Final/wildfly-dist-11.0.0.Final.tar.gz
docker build -t wildfly:11.0.0.Final-patched .
docker run -d -p 8080:8080 wildfly:11.0.0.Final-patched
동료들은 이미지에 자신의 배포 파일을 마운트하거나 확장할 수 있습니다:
FROM wildfly:11.0.0.Final-patched
COPY standalone.xml /opt/jboss/wildfly/standalone/configuration/standalone.xml
COPY myapp.war /opt/jboss/wildfly/standalone/deployments/
| 요청 | 예상 결과 | 결과 |
|---|
Host: localhost:8080 (유효) | 200 OK | ✓ |
Host: evil<script> (잘못된 문자) | 400 Host Header Bad Characters | ✓ |
두 개의 Host: 헤더 (중복, raw TCP) | 400 Bad Request | ✓ |
Host: localhost:99999 (잘못된 포트) | 400 Host Header Malformed Port | ✓ |