CVE-2025-12543

Undertow's Hostile Hospitality: Bypassing Validation via Malformed Headers

Alon Barad
Alon Barad
Software Engineer

Jan 12, 2026·6 min read

Executive Summary (TL;DR)

Undertow failed to reject malformed `Host` headers (like `Host: evil.com `), violating RFC 7230. By sending headers that proxies might normalize but Undertow accepts as-is, attackers can poison web caches, hijack sessions, or trigger SSRF. Rated Critical (9.6), this affects JBoss EAP, WildFly, and Keycloak.

A critical input validation failure in the Undertow HTTP server core allows attackers to supply malformed Host headers (containing spaces, tabs, or illegal characters) without triggering a 400 Bad Request. This parsing leniency creates a dangerous desynchronization between front-end proxies and the back-end server, enabling cache poisoning, SSRF, and session hijacking.

The Hook: The Polite Bouncer Problem

Web servers are essentially digital bouncers. Their job is simple: check the ID (the request), make sure the guest is on the list (routing), and kick out anyone acting drunk (malformed packets). Undertow, the high-performance non-blocking web server behind heavy hitters like JBoss EAP and WildFly, usually takes this job seriously. It handles millions of concurrent connections with the efficiency of a German train schedule.

But here’s the thing about efficiency: sometimes, in the name of speed, you stop checking the fine print. CVE-2025-12543 is exactly that kind of slip-up. It turns out Undertow was being a little too polite. When an attacker handed it a Host header that looked like it had been through a blender—full of trailing spaces, tabs, or garbage characters—Undertow didn't throw them out. It invited them in.

This might sound trivial. "So what if there's a space at the end of the hostname?" The problem isn't the space itself; it's how everyone else treats that space versus how Undertow treats it. In the world of HTTP desyncs and cache poisoning, ambiguity is the mother of all exploits.

The Flaw: RFCs Are Just Suggestions, Right?

To understand why this breaks things, we have to look at RFC 7230. The spec is crystal clear: a Host header field value must be a uri-host and an optional port. It does not allow for whitespace, control characters, or multiple colons. A strictly compliant server should look at Host: example.com (notice the trailing space) and immediately return 400 Bad Request.

Undertow, however, missed this check in its undertow-core component. The parsing logic read the header value but failed to strictly validate the character set before processing the request. This creates a classic Parser Logic Differential.

Imagine a setup where Nginx sits in front of Undertow. You send Host: internal-admin.local . Nginx sees the space, thinks "that's invalid but I'll be nice and trim it," and forwards Host: internal-admin.local to the backend. Or worse, a caching proxy sees the space, treats it as a unique cache key, but Undertow strips it and serves the content for the admin panel. Now the proxy has cached the admin panel under a key that an external user can access. You've just poisoned the cache because two systems couldn't agree on what a "Host" actually looks like.

The Code: The Silent Failure

The vulnerability lies deep within the HTTP parsing state machine of undertow-core. In a secure implementation, the parser iterates through the header bytes and halts execution if a byte falls outside the allowed range (alphanumeric, dots, colons, brackets for IPv6).

While the exact proprietary source diff for JBoss isn't public, the logic flaw resembles this pseudocode scenario:

// VULNERABLE LOGIC (Simplified)
String hostHeader = request.getHeader("Host");
if (hostHeader != null) {
    // No validation! Just assumes it's fine.
    exchange.setDestinationAddress(InetAddress.getByName(hostHeader.trim()));
}

The fix involves strictly enforcing the grammar. If the parser encounters a space, tab (\t), or anything that isn't a valid hostname character before the CRLF, it must abort. The patched version effectively does this:

// PATCHED LOGIC (Conceptual)
String hostHeader = request.getHeader("Host");
if (!isValidHostHeader(hostHeader)) {
    // RFC 7230 strict enforcement
    throw new BadRequestException("Invalid character in Host header");
}
// Proceed only if clean

By forcing the 400 Bad Request, the server prevents the request from ever reaching the application logic, killing the ambiguity before it can be weaponized.

The Exploit: Poisoning the Well

Let's walk through a Cache Poisoning scenario. We have a public facing website public.com served by a reverse proxy, and a restricted app internal.com hosted on the same Undertow backend.

Step 1: The Probe The attacker sends a request with a malformed host header:

GET / HTTP/1.1
Host: internal.com%20
X-Forwarded-Host: public.com

Step 2: The Confusion The front-end proxy (e.g., Varnish or a CDN) parses Host. It might see the encoded space (%20) or a raw space and decide, "I don't know what internal.com is, so I'll just pass this through or cache it as a distinct entry."

Step 3: The Execution Undertow receives the request. Due to the bug, it accepts internal.com (with the space), trims it internally or ignores the suffix, and routes the request to the internal.com virtual host. It generates a response containing sensitive internal data or a redirect to an internal login page.

Step 4: The Poison The response travels back through the proxy. The proxy sees a valid 200 OK and caches it. However, it might cache it associated with the context of public.com if the attacker manipulated other headers, or it effectively caches the "Internal Admin Page" as the response for the malformed request. If the attacker can force other users' browsers to issue that specific malformed request (via XSS or open redirect), they get served the cached internal content.

The Impact: Why Critical (9.6)?

You might wonder why a "bad header" gets a CVSS score of 9.6. It's rare for a non-RCE bug to score this high. The reason lies in the Scope Change (S:C) metric.

This vulnerability doesn't just affect the Undertow server; it corrupts the integrity of the infrastructure around it. By exploiting this, an attacker can:

  1. Mass Cache Poisoning: Serve malicious JavaScript to every user visiting the site by poisoning the main index page in the shared cache.
  2. SSRF: If the application uses the Host header to construct upstream API calls (common in microservices), the attacker can force the server to scan internal IP addresses.
  3. Session Hijacking: If cookies are set with Domain=<Host>, a malformed header allows attackers to set cookies for parent domains or bypass cookie scoping protections.

It is a "skeleton key" for HTTP routing logic.

The Fix: Closing the Window

If you are running JBoss EAP, WildFly, or Keycloak, you need to patch immediately. The patch ensures that undertow-core acts like a grumpy librarian: strict, unforgiving, and compliant with the rules.

Immediate Mitigation: If you cannot patch right away, you must enforce validation at your edge. Configure your WAF or Load Balancer (Nginx, HAProxy, AWS ALB) to drop any request where the Host header contains whitespace or non-alphanumeric characters (excluding dots and colons). Do not let the malformed packets reach the backend.

Long Term: Update to the patched versions of undertow-core (e.g., via Red Hat's RHSA-2026:0383/0384). Verify your configuration specifically for undertow listeners to ensure no legacy options are enabling lenient parsing.

Technical Appendix

CVSS Score
9.6/ 10
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:N
EPSS Probability
0.13%
Top 66% most exploited

Affected Systems

Red Hat JBoss Enterprise Application Platform (EAP) 7Red Hat JBoss Enterprise Application Platform (EAP) 8Red Hat Single Sign-On (Keycloak) 7WildFly (versions prior to fix)Red Hat Data Grid 8Red Hat Build of Apache Camel

Affected Versions Detail

Product
Affected Versions
Fixed Version
JBoss EAP
Red Hat
< 8.1 (Jan 2026 Update)8.1.0.GA-patch
Undertow Core
JBoss.org
< 2.3.21.Final2.3.21.Final
AttributeDetail
CWE IDCWE-20 (Improper Input Validation)
CVSS v3.19.6 (Critical)
Attack VectorNetwork (Remote)
ImpactCache Poisoning, SSRF, Session Hijacking
EPSS Score0.13%
Exploit StatusPoC Available / Weaponized Context
CWE-20
Improper Input Validation

The product does not validate or incorrectly validates input that can affect the control flow or data flow of a program.

Vulnerability Timeline

Vulnerability reported to Red Hat by Ahmet Artuç
2025-10-31
CVE-2025-12543 assigned and published
2026-01-07
Red Hat releases security advisories and patches
2026-01-08

Subscribe to updates

Get the latest CVE analysis reports delivered to your inbox.