kavin71725/CVE-2025-12543-Fix-for-Wildfly
GitHub: kavin71725/CVE-2025-12543-Fix-for-Wildfly
针对 WildFly 11 中 Undertow 的 CVE-2025-12543 Host 头验证漏洞,通过字节码后移修补提供可直接使用的 Docker 基础镜像。
Stars: 0 | Forks: 0
# WildFly 11.0.0.Final 基础镜像 — CVE-2025-12543 补丁
## 概述
本仓库提供了一个基于 **WildFly 11.0.0.Final** 构建的 Docker 基础镜像,并包含针对 **CVE-2025-12543**(Undertow 中一个严重的 Host 头验证漏洞)的后移(backported)修复。
该镜像旨在作为基础镜像提供给同事使用。他们可以在其之上部署自己的 `.war` 应用程序和 `standalone.xml`。
## CVE-2025-12543 摘要
| 字段 | 详情 |
|-------------|--------|
| **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?
其他用户仍在使用 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`
构建最终镜像。它执行以下操作:
1. 使用 `bitnamilegacy/java:1.8.432-7-debian-12-r2` (OpenJDK 1.8.0_432) 作为基础
2. 将 WildFly 11 解压到 `/opt/jboss/wildfly`
3. 使用修补后的版本替换原始的 `undertow-core-1.4.18.Final.jar`
4. 通过 `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](https://github.com/undertow-io/undertow/pull/1857) (UNDERTOW-2656)。
所有常量(`IP4_EXACT`、`IP6_EXACT`、字符表)都是**自包含的** —— 不依赖 Undertow 2.x 中新增的 API。在每次 HTTP 请求时,它会验证:
- Host 头存在(HTTP/1.1 要求)
- 仅有一个 Host 头(无重复)
- 端口为数字且在 1–65535 范围内
- IP 字面量(IPv4、IPv6、IPvFuture)格式正确
- 主机名字符是有效的 RFC 3986 reg-name 字符
- 任何违规都会以 `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.txt`
CVE 扫描报告(生成于 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
```
## 修补过程
### 1. 识别漏洞
扫描报告 (`result-20260401-0230.txt`) 确认 `undertow-core-1.4.18.Final` 受到 CVE-2025-12543 (CVSS 9.6) 的影响。
### 2. 研究上游修复
该修复位于 Undertow [PR #1857](https://github.com/undertow-io/undertow/pull/1857) 中,已合并到 `main` (2026-01-09) 并向后移植到 2.2.x 和 2.3.x。该修复添加了 `HostHeaderHandler.java` 并将其接入 `HttpReadListener` 以验证每个请求的 Host 头。
### 3. 评估直接升级的可行性
Undertow 1.4.x → 2.2.x 是一个**主版本跳跃**,包含破坏性的 API 更改。WildFly 11 通过 JBoss Modules 与 Undertow 1.4.x 紧密耦合。直接替换 JAR 会在启动时导致 `ClassNotFoundException` / `NoSuchMethodError`。
### 4. 后移 `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
```
### 5. 通过 Javassist 修补 `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/
```
### 6. 重新打包 JAR
复制原始 JAR 并注入修补/新增的 class 文件:
```
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
```
### 7. 更新 Dockerfile
为修补后的 JAR 添加一个 `COPY` 指令,并替换镜像中的原始 JAR:
```
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
```
### 8. 构建并验证
```
docker build -t wildfly:11.0.0.Final-patched .
```
验证:
```
# 有效的 Host header — 应返回 200
curl -v -H "Host: localhost:8080" http://localhost:8080/
# Host 中包含错误字符 — 应返回 400 Host Header Bad Characters
curl -v -H "Host: evil