Imagem base Docker com correção retroativa de validação de cabeçalho Host para CVE-2025-12543 no Undertow 1.4.x, permitindo a implantação segura de aplicações WildFly 11.
Este repositório fornece uma imagem Docker base construída sobre o WildFly 11.0.0.Final com uma correção portada para CVE-2025-12543, uma vulnerabilidade crítica de validação do cabeçalho Host no Undertow.
A imagem destina-se a ser fornecida a colegas como base. Eles podem implantar sua própria aplicação .war e standalone.xml sobre ela.
| Campo | Detalhe |
|---|
| ID CVE | CVE-2025-12543 |
| Componente | io.undertow:undertow-core |
| Gravidade | Crítica (CVSS 9.6) |
| Versões afetadas | Todas as versões < 2.2.39 (incluindo 1.4.x) |
| Corrigido em | Undertow 2.2.39 / 2.3.22 |
| Versão do WildFly 11 | undertow-core-1.4.18.Final — afetada |
O Undertow não valida corretamente o cabeçalho Host em requisições HTTP recebidas. Requisições contendo cabeçalhos Host malformados ou maliciosos são processadas sem rejeição, permitindo:
Outros usuários ainda estão no WildFly 11, e não há recursos ou planos atuais para atualização. A correção foi portada diretamente para o JAR Undertow 1.4.18.Final.
.
├── Dockerfile # Definição principal da imagem
├── README.md
├── wildfly-dist-11.0.0.Final.tar.gz # Arquivo de distribuição do WildFly 11
├── reports/
│ ├── result-20260401-0230.txt # Relatório de varredura CVE que identificou a vulnerabilidade
│ └── wildfly_11.0.0.Final_*.txt # Relatórios de varredura adicionais
└── patch/
├── src/
│ ├── HostHeaderHandler.java # Correção portada — nova classe de manipulador
│ ├── HttpReadListener_only.java # Código fonte do HttpReadListener descompilado + corrigido (referência)
│ └── PatchHttpReadListener.java # Ferramenta de correção de bytecode Javassist
├── build.sh # Script de compilação — reconstrói o JAR corrigido do zero
├── undertow-core-1.4.18.Final.jar # JAR original (não corrigido) — mantido para referência
└── undertow-core-1.4.18.Final-patched.jar # JAR corrigido injetado na imagem
DockerfileConstrói a imagem final. Ele:
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 original pela versão corrigidastandalone.sh -b 0.0.0.0 (escuta em todas as interfaces)patch/undertow-core-1.4.18.Final-patched.jarO JAR Undertow corrigido. É idêntico ao original exceto por duas alterações:
io/undertow/server/handlers/HostHeaderHandler.class (e suas classes internas)io/undertow/server/protocol/http/HttpReadListener.class — injeta HostHeaderHandler no pipeline de requisiçõespatch/src/HostHeaderHandler.javaO manipulador de validação do cabeçalho Host portado. Portado do PR #1857 do Undertow (UNDERTOW-2656).
Todas as constantes (IP4_EXACT, IP6_EXACT, tabelas de caracteres) são autocontidas — sem dependência de APIs adicionadas no Undertow 2.x. Em cada requisição HTTP, ele valida:
400 Bad Request em qualquer violaçãopatch/src/PatchHttpReadListener.javaUm corretor de bytecode Javassist de uso único. Carrega HttpReadListener do JAR original e substitui:
// Antes
Connectors.executeRootHandler(connection.getRootHandler(), exchange);
// Depois
Connectors.executeRootHandler(
HostHeaderHandler.WRAPPER.wrap(connection.getRootHandler()),
exchange
);
Isso injeta HostHeaderHandler automaticamente em cada requisição HTTP, sem exigir uma recompilação completa de HttpReadListener (que depende de classes internas complexas e internals do xnio).
patch/src/HttpReadListener_only.javaCódigo fonte descompilado do HttpReadListener original do Undertow 1.4.18.Final, usado como referência para localizar o ponto de injeção. A versão corrigida deste código fonte também é mantida aqui para fins de auditoria.
reports/result-20260401-0230.txtRelatório de varredura CVE (gerado em 2026-04-01) que identificou CVE-2025-12543 em undertow-core-1.4.18.Final em:
/opt/jboss/wildfly/modules/system/layers/base/io/undertow/core/main/undertow-core-1.4.18.Final.jar
O relatório de varredura (result-20260401-0230.txt) confirmou que undertow-core-1.4.18.Final é afetado pela CVE-2025-12543 (CVSS 9.6).
A correção está no PR #1857 do Undertow, mesclado no main (2026-01-09) e portado para 2.2.x e 2.3.x. A correção adiciona HostHeaderHandler.java e o conecta ao HttpReadListener para validar o cabeçalho Host em cada requisição.
Undertow 1.4.x → 2.2.x é um salto de versão principal com mudanças de API que quebram compatibilidade. O WildFly 11 está fortemente acoplado ao Undertow 1.4.x via JBoss Modules. Uma troca direta de JAR causaria ClassNotFoundException / NoSuchMethodError na inicialização.
HostHeaderHandler.javaEscrever uma versão autocontida de HostHeaderHandler.java compatível com Undertow 1.4.18.Final:
IP4_EXACT, IP6_EXACT) — não disponíveis em NetworkUtils do 1.4.xexchange.isHostIncludedInRequestURI() — não disponível em HttpServerExchange do 1.4.xCompilar contra o classpath do Undertow 1.4.18 + xnio dentro da imagem 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 via JavassistDescompilar HttpReadListener com Procyon para localizar o ponto de injeção:
Connectors.executeRootHandler(this.connection.getRootHandler(), httpServerExchange);
localizado em handleEventWithNoRunningRequest().
Como HttpReadListener possui classes internas anônimas ($1, $2, $3) que não podem ser referenciadas a partir do código fonte descompilado, uma recompilação completa não é viável. Em vez disso, use Javassist (PatchHttpReadListener.java) para instrumentar o bytecode diretamente — substituindo a chamada executeRootHandler para envolver o manipulador raiz com HostHeaderHandler.WRAPPER.
java -cp javassist.jar:undertow-core-1.4.18.Final.jar:out \
PatchHttpReadListener undertow-core-1.4.18.Final.jar out/
Copiar o JAR original e injetar os arquivos de classe corrigidos/novos:
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
Adicionar um COPY para o JAR corrigido e substituir o original dentro da imagem:
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 .
Validação:
# Cabeçalho Host válido — deve retornar 200
curl -v -H "Host: localhost:8080" http://localhost:8080/
# Caracteres ruins no Host — deve retornar 400 Host Header Bad Characters
curl -v -H "Host: evil<script>" http://localhost:8080/
# Cabeçalhos Host duplicados — deve retornar 400 Bad Request
# Nota: curl deduplica cabeçalhos Host internamente, então uma requisição TCP bruta é necessária para este teste
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>&-
# Porta fora do intervalo — deve retornar 400 Host Header Malformed Port
curl -v -H "Host: localhost:99999" http://localhost:8080/
| Requisição | Esperado | Resultado |
|---|---|---|
Host: localhost:8080 (válido) | 200 OK | ✓ |
Host: evil<script> (caracteres ruins) | 400 Host Header Bad Characters | ✓ |
Dois cabeçalhos Host: (duplicado, TCP bruto) | 400 Bad Request | ✓ |
Host: localhost:99999 (porta ruim) | 400 Host Header Malformed Port | ✓ |
HostAntes desta correção, a opção REQUIRE_HOST_HTTP11 do WildFly padrão era false, o que significava que requisições HTTP/1.1 sem cabeçalho Host eram aceitas silenciosamente.
Após esta correção, o HostHeaderHandler aplica estritamente o RFC 7230 — todas as requisições HTTP/1.1 sem cabeçalho Host são rejeitadas com 400 No Host Header, independentemente da configuração REQUIRE_HOST_HTTP11.
Quem pode ser afetado:
GET / HTTP/1.1 simples sem cabeçalho HostO que fazer:
Garanta que todos os clientes HTTP/1.1 incluam um cabeçalho Host. Isso já é exigido pelo RFC 7230 e qualquer biblioteca HTTP padrão (curl, HttpClient do Java, etc.) faz isso automaticamente. Apenas clientes personalizados não conformes ou muito antigos são afetados.
# Isto agora será rejeitado com 400:
GET /health HTTP/1.1
Connection: close
# Isto está correto e funcionará bem:
GET /health HTTP/1.1
Host: seu-servidor:8080
Connection: close
Se você precisar regenerar patch/undertow-core-1.4.18.Final-patched.jar em um novo ambiente (por exemplo, o JAR pré-construído não estiver disponível), use o script de compilação fornecido.
Requisitos: JDK 8, curl, acesso à internet para o Maven Central.
cd patch
bash build.sh
O script irá:
HostHeaderHandler.javaPatchHttpReadListener.java para corrigir o bytecode do HttpReadListener via Javassistundertow-core-1.4.18.Final-patched.jarApós a conclusão, prossiga com docker build normalmente.
Nota:
wildfly-dist-11.0.0.Final.tar.gznão está incluído neste repositório (excede o limite de 100 MB do GitHub). Baixe-o do 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
Colegas podem montar ou estender a imagem com sua própria implantação:
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/