Feb 21, 2026·5 min read·172 visits
Undertow (the engine behind JBoss/WildFly) wasn't validating Host headers properly. It accepted duplicates, illegal ports, and garbage characters. This allows attackers to trick the server into generating malicious links or poisoning downstream caches. Fix is available in 2.3.21.Final.
A critical input validation flaw in the Undertow HTTP server core allows attackers to bypass protocol constraints using malformed Host headers. By failing to enforce RFC 7230, Undertow opens the door to Web Cache Poisoning, SSRF, and Session Hijacking in widely used Java application servers like WildFly and JBoss EAP.
In the world of HTTP, the Host header is the ID card of a request. It tells the server who you are trying to reach in a crowded room of virtual hosts. RFC 7230 is very specific about this card: you get exactly one, and it must look a certain way.
Undertow, the high-performance non-blocking I/O web server used by Red Hat's heavy hitters (WildFly, JBoss EAP), apparently decided these rules were more like "guidelines."
CVE-2025-12543 isn't a complex buffer overflow or a magical deserialization gadget. It's a fundamental failure to say "No" to bad input. By allowing multiple Host headers, malformed ports (port 90000, anyone?), and garbage characters, Undertow created a playground for ambiguity. And in security, ambiguity is where the exploits live.
The core issue lies in io.undertow:undertow-core. When a request comes in, the server parses the headers to decide how to route the traffic and how to construct absolute URLs for redirects or references.
Prior to the fix, Undertow suffered from multiple personality disorder regarding the Host header. It failed to validate three key things:
Host headers.This matters because modern web architectures are layered. You have CDNs, Load Balancers, Reverse Proxies, and finally the Application Server. If the Load Balancer looks at the first Host header (legitimate) and Undertow looks at the second (malicious), you have a classic HTTP Desync or Cache Poisoning scenario. The front-end thinks it's serving good.com, but the back-end is generating content for evil.com.
The fix involved introducing a completely new handler, HostHeaderHandler.java, to act as a bouncer. Before this, the validation was virtually non-existent.
Here is a simplified look at the logic that had to be added to stop the madness. Notice the explicit checks that were missing before:
// In HostHeaderHandler.java (The Fix)
String hostHeader = exchange.getRequestHeaders().getFirst(Headers.HOST);
// 1. Check for multiple headers
if (exchange.getRequestHeaders().count(Headers.HOST) > 1) {
// RFC 7230: Must reject with 400
exchange.setStatusCode(StatusCodes.BAD_REQUEST);
exchange.endExchange();
return;
}
// 2. Parse and Validate Port
if (colonIndex != -1) {
String portString = hostHeader.substring(colonIndex + 1);
try {
int port = Integer.parseInt(portString);
// The "Whoops" moment: valid ports are 0-65535
if (port < 0 || port > 65535) {
throw new NumberFormatException();
}
} catch (NumberFormatException e) {
exchange.setStatusCode(StatusCodes.BAD_REQUEST);
return;
}
}The fact that this logic had to be added implies that previously, you could send Host: internal-admin:99999 and Undertow would likely just shrug and pass it up the stack to the application, which might crash or, worse, try to use it.
Let's weaponize this. The most practical attack vector here is Web Cache Poisoning.
Imagine a JBoss EAP server sitting behind a caching reverse proxy (like Varnish or Akamai). The proxy uses the Host header as part of the cache key.
Step 1: The attacker sends a request with a malformed port that the Proxy ignores or sanitizes, but Undertow accepts.
GET /reset-password HTTP/1.1
Host: target.com
Host: evil.comStep 2: The Proxy sees target.com. It doesn't have a cached copy, so it forwards the request.
Step 3: Undertow receives the request. Due to the flaw, it might process the second header evil.com as the valid authority for generating links.
Step 4: The application generates a password reset link using the server's view of the Host:
https://evil.com/reset-token?user=admin
Step 5: The Proxy receives this response. Since it thinks the request was for target.com, it caches this malicious response.
Step 6: A legitimate user visits target.com/reset-password. The Proxy serves the cached content. The user clicks the link and sends their reset token directly to the attacker.
You might be thinking, "It's just a header, relax." But the CVSS 9.6 (Critical) reflects the reality of how deeply the Host header is trusted in Java ecosystems.
1. SSRF (Server-Side Request Forgery): If the application uses request.getServerName() to build internal service calls, an attacker can redirect internal traffic to arbitrary hosts.
2. Data Leakage: As shown in the exploit above, password reset tokens and session IDs are frequently leaked via Location headers in 302 redirects generated by the container.
3. Access Control Bypass: Many internal apps use host-based checking to allow administrative access (e.g., "Only allow requests from localhost or admin.internal"). By manipulating the header, an attacker can spoof these trusted origins.
This isn't just a bug; it's a foundational trust failure in the HTTP processing pipeline.
Red Hat and the Undertow team have released patches that enforce strict RFC compliance. If you are running WildFly, JBoss EAP, or standalone Undertow, you need to update immediately.
Fixed Versions:
If patching is administratively impossible right now (we've all been there), your best defense is a Web Application Firewall (WAF).
Configure your WAF to:
Host header.Don't rely on the app server to save you; clearly, it wasn't designed to.
CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:H/I:H/A:L| Product | Affected Versions | Fixed Version |
|---|---|---|
Undertow Red Hat / JBoss | < 2.2.39.Final | 2.2.39.Final |
Undertow Red Hat / JBoss | 2.3.0 - 2.3.20.Final | 2.3.21.Final |
| Attribute | Detail |
|---|---|
| CWE | CWE-20 (Improper Input Validation) |
| CVSS | 9.6 (Critical) |
| Attack Vector | Network |
| Impact | Cache Poisoning, SSRF, Session Hijacking |
| EPSS | 0.076% |
| Exploit Status | POC Available (Unit Tests) |
The product receives input or data, but does not validate or incorrectly validates that the input has the properties that are required to process the data safely and correctly.