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