CVE-2026-65905

Authorization Bypass
Affects
Apache Tomcat
in
Apache Tomcat
No items found.
Versions
>=8.5.0 <=8.5.100

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 web server and servlet container, maintained by the Apache Software Foundation, that implements the Jakarta Servlet, Jakarta Pages (JSP), Jakarta Expression Language, and Jakarta WebSocket specifications and provides a pure-Java HTTP environment for running Java web applications.

An authorization bypass vulnerability (CVE-2026-65905) has been identified in the DIGEST authenticator of Apache Tomcat, which allows an attacker who has captured a valid DIGEST-authenticated request from a legitimate user to replay that request once against the server. The authenticator tracks a sliding window of nonce count values already seen for each nonce so that a repeated nonce count is rejected as a replay, but the window bookkeeping is performed in the wrong order, so a request whose nonce count sits on the upper boundary of the window erases its own replay marker as it is accepted.

Per OWASP: Confirmation of the user's identity, authentication, and session management is critical to protect against authentication-related attacks.

This issue affects all versions of the Apache Tomcat 8.5.x line, from 8.5.0 through the final community release 8.5.100.

Module Info

Vulnerability Info

This Low-severity vulnerability is found in the org.apache.tomcat:tomcat-catalina package in all versions of the Apache Tomcat 8.5.x line, and in the same classes as they are repackaged into org.apache.tomcat.embed:tomcat-embed-core. The flaw lives in org.apache.catalina.authenticator.DigestAuthenticator, the authenticator engaged when a web application declares <auth-method>DIGEST</auth-method> in its deployment descriptor.

Under DIGEST authentication the server issues a nonce and the client returns it on each request together with a nonce count (nc) that it increments every time it reuses that nonce. To stop a captured request from being replayed, Tomcat records which nonce counts it has already accepted for a given nonce. The nested NonceInfo class holds that state: a boolean array seen whose length is the configured nonceCountWindowSize (the shipped default is 100), an offset equal to half that window, and a counter count that tracks how far the window has advanced. Every DIGEST request that presents qop and nc is checked through nonceCountValid():

public synchronized boolean nonceCountValid(long nonceCount) {
    if ((count - offset) >= nonceCount || (nonceCount > count - offset + seen.length)) {
        return false;
    }
    int checkIndex = (int) ((nonceCount + offset) % seen.length);
    if (seen[checkIndex]) {
        return false;
    } else {
        seen[checkIndex] = true;
        seen[count % seen.length] = false;
        count++;
        return true;
    }
}

The accepted range of nonce counts is (count - offset, count - offset + seen.length], and a value's slot in the array is checkIndex. When count advances from c to c + 1, the value that drops out of the window is c - offset + 1, whose slot is (c + 1) % seen.length. The method, however, clears seen[count % seen.length] before count is advanced, so it clears slot c rather than slot c + 1.

That one-statement ordering error opens a hole at exactly one position in the window. Substituting the upper boundary of the window, nonceCount == count - offset + seen.length, gives checkIndex == (count + seen.length) % seen.length == count % seen.length: the slot the call has just marked as seen is the same slot the very next statement clears. A request whose nonce count sits on that boundary is therefore accepted, un-marked, and can be presented a second time and accepted again. With the shipped default nonceCountWindowSize of 100 and a freshly issued nonce, the boundary value is nc = 50, and the sequence 50, 50 is accepted twice, while a third presentation of 50 is rejected. The upper boundary is the only value in the window that behaves this way.

Exploitation is correspondingly narrow. The attacker must have captured a complete, valid DIGEST-authenticated request from a legitimate user, including the username, realm, nonce, nc, cnonce, qop, and response fields, and the captured request's nonce count must sit on the boundary of the server's current window for that nonce. Fewer than nonceCountWindowSize requests must have been made against the nonce, because once the window has advanced past a full sweep the array retains stale entries and the boundary request is rejected outright. The nonce must also still be cached, which by default means within five minutes and within the most recent 1000 nonces. A successful attack replays one already-authorized request one extra time: it recovers no credentials, authenticates as no other user, and grants no privilege the captured request did not already exercise, so its practical significance is confined to non-idempotent operations such as a state-changing POST. DIGEST authentication is also not a default configuration, and no web application shipped with Tomcat uses it. The Apache Tomcat security team rates this issue Low and published no CVSS vector for it.

The same ordering error has a second, non-attacker-controlled effect: because the slot that genuinely leaves the window is never cleared, a later legitimate nonce count that wraps onto that slot is wrongly rejected as a replay. That symptom harms legitimate clients rather than serving an attacker, and correcting the ordering removes it as well.

Mitigation

Only recent major lines of Apache Tomcat are community-supported. The affected 8.5.x line reached End-of-Life on March 31, 2024 (final community release 8.5.100) and will not receive public updates to address this issue.

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

  • Upgrade to a currently supported Apache Tomcat major line (9.0.x or later) that contains the fix.
  • Leverage a commercial support partner like HeroDevs for post-EOL security support.

Credits

  • 4ra1n (finder)
  • pyn3rd (finder)
  • unam4 (finder)
Vulnerability Details
Severity
Level
CVSS Assessment
Low
>=0 <4
Medium
>=4 <6
High
>=6 <8
Critical
>=8 <10
Low
ID
CVE-2026-65905
PROJECT Affected
Apache Tomcat
Versions Affected
>=8.5.0 <=8.5.100
NES Versions Affected
Published date
August 25, 2026
≈ Fix date
September 2, 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.