Imagen base de Docker con corrección retroportada de validación de cabecera Host para CVE-2025-12543 en Undertow 1.4.x, permitiendo el despliegue seguro de aplicaciones WildFly 11.
Este repositorio proporciona una imagen base Docker construida sobre WildFly 11.0.0.Final con una corrección retroportada para CVE-2025-12543, una vulnerabilidad crítica de validación del encabezado Host en Undertow.
La imagen está destinada a ser proporcionada a colegas como base. Pueden desplegar su propia aplicación .war y standalone.xml sobre ella.
| Campo | Detalle |
|---|
| ID CVE | CVE-2025-12543 |
| Componente | io.undertow:undertow-core |
| Severidad | Crítica (CVSS 9.6) |
| Versiones afectadas | Todas las versiones < 2.2.39 (incluyendo 1.4.x) |
| Corregido en | Undertow 2.2.39 / 2.3.22 |
| Versión de WildFly 11 | undertow-core-1.4.18.Final — afectada |
Undertow no valida correctamente el encabezado Host en las solicitudes HTTP entrantes. Las solicitudes que contienen encabezados Host malformados o maliciosos son procesadas sin ser rechazadas, permitiendo:
Otros usuarios aún están en WildFly 11, y no hay recursos ni planes actuales para actualizar. La corrección fue retroportada directamente al JAR Undertow 1.4.18.Final.
.
├── Dockerfile # Definición de la imagen principal
├── README.md
├── wildfly-dist-11.0.0.Final.tar.gz # Archivo de distribución de WildFly 11
├── reports/
│ ├── result-20260401-0230.txt # Informe de escaneo CVE que identificó la vulnerabilidad
│ └── wildfly_11.0.0.Final_*.txt # Informes de escaneo adicionales
└── patch/
├── src/
│ ├── HostHeaderHandler.java # Corrección retroportada — nueva clase de manejador
│ ├── HttpReadListener_only.java # Código fuente descompilado + parcheado de HttpReadListener (referencia)
│ └── PatchHttpReadListener.java # Herramienta de parcheo de bytecode Javassist
├── build.sh # Script de compilación — reconstruye el JAR parcheado desde cero
├── undertow-core-1.4.18.Final.jar # JAR original (sin parchear) — conservado como referencia
└── undertow-core-1.4.18.Final-patched.jar # JAR parcheado inyectado en la imagen
DockerfileConstruye la imagen final.:
bitnamilegacy/java:1.8.432-7-debian-12-r2 (OpenJDK 1.8.0_432) como base/opt/jboss/wildflyundertow-core-1.4.18.Final.jar con la versión parcheadastandalone.sh -b 0.0.0.0 (se vincula a todas las interfaces)patch/undertow-core-1.4.18.Final-patched.jarEl JAR Undertow parcheado. Es idéntico al original excepto por dos cambios:
io/undertow/server/handlers/HostHeaderHandler.class (y sus clases internas)io/undertow/server/protocol/http/HttpReadListener.class — inyecta HostHeaderHandler en la tubería de solicitudespatch/src/HostHeaderHandler.javaEl manejador de validación del encabezado Host retroportado. Portado desde el PR #1857 de Undertow (UNDERTOW-2656).
Todas las constantes (IP4_EXACT, IP6_EXACT, tablas de caracteres) son autocontenidas — sin dependencia de APIs añadidas en Undertow 2.x. En cada solicitud HTTP, valida:
400 Bad Request ante cualquier violaciónpatch/src/PatchHttpReadListener.javaUn parcheador de bytecode Javassist de un solo uso. Carga HttpReadListener del JAR original y reemplaza:
// Before
Connectors.executeRootHandler(connection.getRootHandler(), exchange);
// After
Connectors.executeRootHandler(
HostHeaderHandler.WRAPPER.wrap(connection.getRootHandler()),
exchange
);
Esto inyecta HostHeaderHandler automáticamente en cada solicitud HTTP, sin requerir una recompilación completa de HttpReadListener (que depende de complejas clases internas e internals de xnio).
patch/src/HttpReadListener_only.javaCódigo fuente descompilado del HttpReadListener original de Undertow 1.4.18.Final, utilizado como referencia para localizar el punto de inyección. La versión parcheada de este código también se conserva aquí con fines de auditoría.
reports/result-20260401-0230.txtInforme de escaneo CVE (generado 2026-04-01) que identificó CVE-2025-12543 en undertow-core-1.4.18.Final en:
/opt/jboss/wildfly/modules/system/layers/base/io/undertow/core/main/undertow-core-1.4.18.Final.jar
El informe de escaneo (result-20260401-0230.txt) confirmó que undertow-core-1.4.18.Final está afectado por CVE-2025-12543 (CVSS 9.6).
La corrección está en el PR #1857 de Undertow, fusionada en main (2026-01-09) y retroportada a 2.2.x y 2.3.x. La corrección añade HostHeaderHandler.java y lo conecta en HttpReadListener para validar el encabezado Host en cada solicitud.
Undertow 1.4.x → 2.2.x es un salto de versión mayor con cambios de API disruptivos. WildFly 11 está fuertemente acoplado a Undertow 1.4.x a través de JBoss Modules. Un intercambio directo de JAR provocaría ClassNotFoundException / NoSuchMethodError al inicio.
HostHeaderHandler.javaEscribir una versión autocontenida de HostHeaderHandler.java compatible con Undertow 1.4.18.Final:
IP4_EXACT, IP6_EXACT) — no disponibles en NetworkUtils de 1.4.xexchange.isHostIncludedInRequestURI() — no disponible en HttpServerExchange de 1.4.xCompilar contra el classpath de Undertow 1.4.18 + xnio dentro de la imagen WildFly:
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 mediante JavassistDescompilar HttpReadListener con Procyon para localizar el punto de inyección:
Connectors.executeRootHandler(this.connection.getRootHandler(), httpServerExchange);
ubicado en handleEventWithNoRunningRequest().
Debido a que HttpReadListener tiene clases internas anónimas ($1, $2, $3) que no pueden ser referenciadas desde el código fuente descompilado, una recompilación completa no es factible. En su lugar, usar Javassist (PatchHttpReadListener.java) para instrumentar el bytecode directamente — reemplazando la llamada a executeRootHandler para envolver el manejador raíz con HostHeaderHandler.WRAPPER.
java -cp javassist.jar:undertow-core-1.4.18.Final.jar:out \
PatchHttpReadListener undertow-core-1.4.18.Final.jar out/
Copiar el JAR original e inyectar los archivos de clase parcheados/nuevos:
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
Añadir un COPY para el JAR parcheado y reemplazar el original dentro de la imagen:
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 .
Validación:
# Host header válido — debería devolver 200
curl -v -H "Host: localhost:8080" http://localhost:8080/
# Caracteres no válidos en Host — debería devolver 400 Host Header Bad Characters
curl -v -H "Host: evil<script>" http://localhost:8080/
# Encabezados Host duplicados — debería devolver 400 Bad Request
# Nota: curl elimina internamente los encabezados Host duplicados, por lo que se requiere una solicitud TCP sin procesar para esta prueba
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>&-
# Puerto fuera de rango — debería devolver 400 Host Header Malformed Port
curl -v -H "Host: localhost:99999" http://localhost:8080/
| Solicitud | Esperado | Resultado |
|---|---|---|
Host: localhost:8080 (válido) | 200 OK | ✓ |
Host: evil<script> (caracteres no válidos) | 400 Host Header Bad Characters | ✓ |
Dos encabezados Host: (duplicado, TCP sin procesar) | 400 Bad Request | ✓ |
Host: localhost:99999 (puerto no válido) | 400 Host Header Malformed Port | ✓ |
HostAntes de este parche, la opción REQUIRE_HOST_HTTP11 de WildFly tenía un valor predeterminado de false, lo que significaba que las solicitudes HTTP/1.1 sin un encabezado Host eran aceptadas silenciosamente.
Después de este parche, el HostHeaderHandler aplica estrictamente RFC 7230 — todas las solicitudes HTTP/1.1 sin un encabezado Host son rechazadas con 400 No Host Header, independientemente de la configuración de REQUIRE_HOST_HTTP11.
Quiénes pueden verse afectados:
GET / HTTP/1.1 sin un encabezado HostQué hacer:
Asegurarse de que todos los clientes HTTP/1.1 incluyan un encabezado Host. Esto ya es requerido por RFC 7230 y cualquier biblioteca HTTP estándar (curl, HttpClient de Java, etc.) lo hace automáticamente. Solo los clientes personalizados no conformes o muy antiguos se ven afectados.
# Esto ahora será rechazado con 400:
GET /health HTTP/1.1
Connection: close
# Esto es correcto y funcionará bien:
GET /health HTTP/1.1
Host: your-server:8080
Connection: close
Si necesita regenerar patch/undertow-core-1.4.18.Final-patched.jar en un entorno nuevo (por ejemplo, el JAR preconstruido no está disponible), use el script de compilación proporcionado.
Requisitos: JDK de Java 8, curl, acceso a internet a Maven Central.
cd patch
bash build.sh
El script hará lo siguiente:
HostHeaderHandler.javaPatchHttpReadListener.java para parchear el bytecode de HttpReadListener mediante Javassistundertow-core-1.4.18.Final-patched.jarDespués de que termine, proceda con docker build como de costumbre.
Nota:
wildfly-dist-11.0.0.Final.tar.gzno está incluido en este repositorio (supera el límite de 100 MB de GitHub). Descárguelo desde Maven Central antes de construir: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
Los colegas pueden montar o extender la imagen con su propio despliegue:
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/