CVE-2026-42498

Content Spoofing
Affects
Apache Tomcat
in
Apache Tomcat
No items found.
Versions
>=8.5.0 <=8.5.100, >=9.0.2 <=9.0.117, >=10.1.0-M1 <=10.1.54, >=11.0.0-M1 <=11.0.21
Exclamation circle icon
Patch Available

This Vulnerability has been fixed in the Never-Ending Support (NES) version offered by HeroDevs.

Overview

Apache Tomcat is an open-source implementation of the Jakarta Servlet, Jakarta Server Pages, Jakarta Expression Language, Jakarta WebSocket, Jakarta Annotations, and Jakarta Authentication specifications, providing a pure Java HTTP web server environment for running Java code. It is one of the most widely used Java application servers.

A low-severity vulnerability (CVE-2026-42498) has been identified in the WebSocket client built into Apache Tomcat. When an outbound WebSocket request was authenticated and then followed an HTTP redirect, Tomcat's WebSocket client retained the computed Authorization (or Proxy-Authorization) header in its shared userProperties map and presented it again to the redirect target host, potentially disclosing the credential to a different origin than the one the application intended to authenticate to.

Per OWASP: Information Exposure is the intentional or unintentional disclosure of information to an actor that is not explicitly authorized to have access to it. Credentials sent to an unintended host as part of an HTTP redirect chain are a common form of this exposure, because the receiving party can replay the credential against the issuing origin.

This issue affects versions 8.5.0 through 8.5.100, 9.0.2 through 9.0.117, 10.1.0-M1 through 10.1.54, and 11.0.0-M1 through 11.0.21 of Apache Tomcat.

Details

Module Info

Vulnerability Info

The vulnerable code lives in WsWebSocketContainer.java, which implements the client-side WebSocket container. When the application calls WebSocketContainer.connectToServer(...) with an outbound URI and the configured credentials, connectToServerRecursive(...) writes the HTTP upgrade request and reads the server response. If the server replies 401 Unauthorized, the helper processAuthenticationChallenge(...) computes the appropriate Authorization value (BASIC or DIGEST) and stores it in the shared userProperties map under Constants.AUTHORIZATION_HEADER_NAME:

userProperties.put(authenticationType.getAuthorizationHeaderName(),
        auth.getAuthorization(requestUri, authenticateHeaders.get(0),
                (String) userProperties.get(authenticationType.getUserNameProperty()),
                (String) userProperties.get(authenticationType.getUserPasswordProperty()),
                (String) userProperties.get(authenticationType.getUserRealmProperty())));

return connectToServerRecursive(clientEndpointHolder, clientEndpointConfiguration, path, redirectSet);

On the subsequent retry, createRequestHeaders(...) reads the cached header back out of userProperties and attaches it to the new request. So far this is intended behaviour: the credential is replayed to the same host that issued the challenge.

The problem appears one step later. If that authenticated request returns a 3xx redirect, connectToServerRecursive(...) resolves the Location header to a new URI (potentially on a different host) and recurses into itself against the redirect target without removing the cached Authorization value from userProperties:

if (isRedirectStatus(httpResponse.status)) {
    // ... resolve and normalize redirectLocation ...
    return connectToServerRecursive(clientEndpointHolder, clientEndpointConfiguration,
            redirectLocation, redirectSet);
}

Because userProperties is the same map used to build every retry, the Authorization header travels along the redirect chain to whatever host the Location header points at. For BASIC authentication this is the literal Basic base64(user:pass) credential. For DIGEST it is a response hash that can still aid an attacker who controls or observes the redirect target.

The same shape applies to proxy authentication: after a successful CONNECT to an authenticated proxy, Constants.PROXY_AUTHORIZATION_HEADER_NAME was likewise retained in userProperties and replayed by later requests in the same connect call.

The fix is to remove the cached header from userProperties at three points in connectToServerRecursive(...). With these clears in place, an authenticated redirect resolves to a new connection that carries no leftover Authorization (or Proxy-Authorization) header, and the credential is not exposed to the redirect target.

Mitigation

Only recent versions of Apache Tomcat are community-supported. Older versions (8.5.x and earlier) will not receive any updates to address this issue. NES for Tomcat includes an update to 8.5.x to address this issue. For more information, see here.

Users of the affected components should apply one of the following mitigations:

  • Upgrade to a patched version of Apache Tomcat.
  • Leverage a commercial support partner like HeroDevs for post-EOL security support.
Vulnerability Details
Severity
Level
CVSS Assessment
Low
>=0 <4
Medium
>=4 <6
High
>=6 <8
Critical
>=8 <10
Low
ID
CVE-2026-42498
PROJECT Affected
Apache Tomcat
Versions Affected
>=8.5.0 <=8.5.100, >=9.0.2 <=9.0.117, >=10.1.0-M1 <=10.1.54, >=11.0.0-M1 <=11.0.21
NES Versions Affected
Published date
May 18, 2026
≈ Fix date
May 12, 2026
Category
Content Spoofing
Vex Document
Download VEXHow do I use it?
Sign up for the latest vulnerability alerts fixed in
NES for Apache Tomcat
Rss feed icon
Subscribe via RSS
or

By clicking “submit” I acknowledge receipt of our Privacy Policy.

Thanks for signing up for our Newsletter! We look forward to connecting with you.
Oops! Something went wrong while submitting the form.