Docker 基础镜像,包含针对 Undertow 1.4.x 中 CVE-2025-12543 的回移植 Host 头验证修复,支持 WildFly 11 应用的安全部署。
本仓库提供了一个基于 WildFly 11.0.0.Final 构建的 Docker 基础镜像,其中包含针对 CVE-2025-12543 的向后移植修复。该漏洞是 Undertow 中一个严重的 Host 头验证漏洞。
该镜像旨在作为基础镜像提供给同事。他们可以在此基础上部署自己的 .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 # Main image definition
├── README.md
├── wildfly-dist-11.0.0.Final.tar.gz # WildFly 11 distribution archive
├── reports/
│ ├── result-20260401-0230.txt # CVE scan report that identified the vulnerability
│ └── wildfly_11.0.0.Final_*.txt # Additional scan reports
└── patch/
├── src/
│ ├── HostHeaderHandler.java # Backported fix — new handler class
│ ├── HttpReadListener_only.java # Decompiled + patched HttpReadListener source (reference)
│ └── PatchHttpReadListener.java # Javassist bytecode patcher tool
├── build.sh # Build script — rebuilds the patched JAR from scratch
├── undertow-core-1.4.18.Final.jar # Original (unpatched) JAR — kept for reference
└── undertow-core-1.4.18.Final-patched.jar # Patched JAR injected into the image
Dockerfile构建最终镜像。它:
bitnamilegacy/java:1.8.432-7-debian-12-r2(OpenJDK 1.8.0_432)作为基础镜像/opt/jboss/wildflyundertow-core-1.4.18.Final.jarstandalone.sh -b 0.0.0.0 启动 WildFly(绑定到所有接口)patch/undertow-core-1.4.18.Final-patched.jar补丁后的 Undertow JAR。除以下两处更改外,与原始 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 并替换:
// Before
Connectors.executeRootHandler(connection.getRootHandler(), exchange);
// After
Connectors.executeRootHandler(
HostHeaderHandler.WRAPPER.wrap(connection.getRootHandler()),
exchange
);
这会将 HostHeaderHandler 自动注入到每个 HTTP 请求中,而无需完整重新编译 HttpReadListener(它依赖于复杂的内部类和 xnio 内部实现)。
patch/src/HttpReadListener_only.java来自 Undertow 1.4.18.Final 的原始 HttpReadListener 反编译源码,用作定位注入点的参考。此源码的补丁版本也保留在此,以供审计。
reports/result-20260401-0230.txtCVE 扫描报告(生成于 2026-04-01),在以下路径识别出 undertow-core-1.4.18.Final 中的 CVE-2025-12543:
/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 classpath 进行编译:
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 .
验证:
# Valid Host header — should return 200
curl -v -H "Host: localhost:8080" http://localhost:8080/
# Bad characters in Host — should return 400 Host Header Bad Characters
curl -v -H "Host: evil<script>" http://localhost:8080/
# Duplicate Host headers — should return 400 Bad Request
# Note: curl deduplicates Host headers internally, so a raw TCP request is required for this test
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>&-
# Port out of range — should return 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 —— 所有不带 Host 头的 HTTP/1.1 请求都会被以 400 No Host Header 拒绝,无论 REQUIRE_HOST_HTTP11 设置如何。
谁可能受影响:
GET / HTTP/1.1 请求的健康检查探针应对措施:
确保所有 HTTP/1.1 客户端都包含 Host 头。RFC 7230 本就有此要求,任何标准 HTTP 库(curl、Java 的 HttpClient 等)都会自动完成。只有不合规或非常老旧的自定义客户端才会受到影响。
# This will now be rejected with 400:
GET /health HTTP/1.1
Connection: close
# This is correct and will work fine:
GET /health HTTP/1.1
Host: your-server:8080
Connection: close
如果需要在新的环境中重新生成 patch/undertow-core-1.4.18.Final-patched.jar(例如预构建的 JAR 不可用),请使用提供的构建脚本。
要求: Java 8 JDK、curl、可访问 Maven Central 的网络连接。
cd patch
bash build.sh
该脚本将:
HostHeaderHandler.javaPatchHttpReadListener.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: 头(重复,原始 TCP) | 400 Bad Request | ✓ |
Host: localhost:99999(非法端口) | 400 Host Header Malformed Port | ✓ |