CVE-2026-75973

Authorization Bypass
Affects
Apache Tomcat
in
Apache Tomcat
No items found.
Versions
>=8.5.0 <=8.5.100, >=9.0.0.M4 <9.0.122, >=10.1.0-M1 <10.1.60, >=11.0.0-M1 <11.0.26

Patch Available.

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 Pages, Jakarta Expression Language, Jakarta WebSocket, Jakarta Annotations, and Jakarta Authentication specifications. It serves Java web applications either as a standalone servlet container and HTTP server or embedded inside an application through the tomcat-embed-core artifact. Its Catalina servlet container (org.apache.tomcat:tomcat-catalina) supplies the request-processing pipeline, including the authenticator Valves that enforce each web application's security constraints, along with connectors, realms, and session management.

A Weak Authentication vulnerability (CVE-2026-75973) has been identified in the Jakarta Authentication implementation of Apache Tomcat, which allows attackers to have their credentials validated, and their roles assigned, by the security realm of a different web application deployed on the same server.

Per OWASP: Confirmation of the user's identity, authentication, and session management is critical to protect against authentication-related attacks. Failures typically lead to unauthorized information disclosure, modification, or destruction of all data or performing a business function outside the user's limits.

This issue affects the Jakarta Authentication (JASPIC) implementation of Apache Tomcat when SimpleAuthConfigProvider is registered as the default authentication configuration provider and more than one web application relies on it.

Details

Module Info

  • Product: Apache Tomcat
  • Affected packages: org.apache.tomcat:tomcat-catalina, org.apache.tomcat.embed:tomcat-embed-core
  • Affected versions: >=8.5.0 <=8.5.100, >=9.0.0.M4 <9.0.122, >=10.1.0-M1 <10.1.60, >=11.0.0-M1 <11.0.26
  • GitHub repository: https://github.com/apache/tomcat
  • Package manager: Maven
  • Fixed in:

Vulnerability Info

This Low-severity vulnerability is found in the org.apache.tomcat:tomcat-catalina package in the Jakarta Authentication implementation of Apache Tomcat.

Jakarta Authentication (formerly JASPIC) lets a container delegate authentication to a pluggable ServerAuthModule. When only a module is supplied by a third party, Tomcat's own SimpleAuthConfigProvider wraps it. When that provider is registered with the AuthConfigFactory as the server-wide default provider, the factory hands the same instance to every deployed web application that has no more specific registration. A conf/jaspic-providers.xml entry with neither a layer nor an application context produces the default registration, and the constructor registers the provider the same way when it is given a factory:

public SimpleAuthConfigProvider(Map<String,String> properties, AuthConfigFactory factory) {
    this.properties = properties;
    if (factory != null) {
        factory.registerConfigProvider(this, null, null, "Automatic registration");
    }
}

The provider created its ServerAuthConfig lazily and cached it in an instance field. Only the first caller's layer, appContext, and handler arguments were ever used; every later call returned the object built for that first caller and silently discarded its own arguments:

private volatile ServerAuthConfig serverAuthConfig;

// ...

@Override
public ServerAuthConfig getServerAuthConfig(String layer, String appContext, CallbackHandler handler)
        throws AuthException {
    ServerAuthConfig serverAuthConfig = this.serverAuthConfig;
    if (serverAuthConfig == null) {
        synchronized (this) {
            if (this.serverAuthConfig == null) {
                this.serverAuthConfig = createServerAuthConfig(layer, appContext, handler, properties);
            }
            serverAuthConfig = this.serverAuthConfig;
        }
    }
    return serverAuthConfig;
}

The caller is the AuthenticatorBase valve, one instance of which sits in the pipeline of each web application. It resolves the ServerAuthConfig on every request that needs authentication, passing its own per web application context id and its own CallbackHandler, and it keeps no per web application copy of the result:

private JaspicState getJaspicState(AuthConfigProvider jaspicProvider, Request request, Response response,
        boolean authMandatory) throws IOException {
    JaspicState jaspicState = new JaspicState();

    jaspicState.messageInfo = new MessageInfoImpl(request.getRequest(), response.getResponse(), authMandatory);

    try {
        CallbackHandler callbackHandler = getCallbackHandler();
        ServerAuthConfig serverAuthConfig =
                jaspicProvider.getServerAuthConfig("HttpServlet", jaspicAppContextID, callbackHandler);
        String authContextID = serverAuthConfig.getAuthContextID(jaspicState.messageInfo);
        jaspicState.serverAuthContext = serverAuthConfig.getAuthContext(authContextID, null, null);
    } catch (AuthException e) {
        // ...
    }

    return jaspicState;
}

The CallbackHandler handed to the provider is the valve's own CallbackHandlerImpl, which is bound to that web application's Context and therefore to that application's configured Realm. Because the shared cache is populated from the arguments of whichever application authenticated a request first, the application context id and the Realm baked into the cached configuration belong to that first application, and every other application on the server inherits them.

The effect appears when the configured ServerAuthModule validates credentials through the container's CallbackHandler (a PasswordValidationCallback) and the applications sharing the provider use different Realms. Any user who holds credentials accepted by the first application's Realm and can reach a protected resource of a second web application supplies the input that reaches this path: their request triggers the cached configuration, so their credentials are validated against the first application's Realm and the roles that Realm returns are the roles applied to the second application's security constraints. A principal with no account in the second application, or with a lower-privileged account there, can therefore be admitted with the identity and roles granted by an unrelated application's Realm, while legitimate users of the second application can be rejected. Because the outcome depends on which application happens to authenticate first after a restart, the access control actually enforced for an application is determined by server-wide request ordering rather than by its own configuration.

Mitigation

Only recent versions of Apache Tomcat are community-supported. The community support version will not receive any updates 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.

Credits

  • 0xCc.zhang (finder)
Vulnerability Details
Severity
Level
CVSS Assessment
Low
>=0 <4
Medium
>=4 <6
High
>=6 <8
Critical
>=8 <10
Low
ID
CVE-2026-75973
PROJECT Affected
Apache Tomcat
Versions Affected
>=8.5.0 <=8.5.100, >=9.0.0.M4 <9.0.122, >=10.1.0-M1 <10.1.60, >=11.0.0-M1 <11.0.26
NES Versions Affected
Published date
September 23, 2026
≈ Fix date
September 25, 2026
Category
Authorization Bypass
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 submitting the form 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.