This is an automated email from the ASF dual-hosted git repository. rmaucher pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/tomcat.git
commit 57ec4a3967cfd181971d0d6c3c1901b857b328c1 Author: opencode <[email protected]> AuthorDate: Fri Oct 16 23:06:23 2026 +0200 Reject digest challenges without a realm in WebSocket client The mandatory realm parameter of the server Digest challenge (RFC 7616 section 3.3) was not validated. If a non-compliant server omitted the realm and the user had not configured one, the client sent an authorization header containing the literal text realm="null" and computed the digest using the string "null" in A1, resulting in a malformed header and a silent authentication failure. Throw an explicit AuthenticationException when the challenge omits the realm, matching the existing handling of a missing qop value. Add a unit test for the case. Found by code review. --- java/org/apache/tomcat/websocket/DigestAuthenticator.java | 3 +++ java/org/apache/tomcat/websocket/LocalStrings.properties | 1 + test/org/apache/tomcat/websocket/TestDigestAuthenticator.java | 9 +++++++++ 3 files changed, 13 insertions(+) diff --git a/java/org/apache/tomcat/websocket/DigestAuthenticator.java b/java/org/apache/tomcat/websocket/DigestAuthenticator.java index f885b55607..0cb58aeb7a 100644 --- a/java/org/apache/tomcat/websocket/DigestAuthenticator.java +++ b/java/org/apache/tomcat/websocket/DigestAuthenticator.java @@ -58,6 +58,9 @@ public class DigestAuthenticator extends Authenticator { Map<String,String> parameterMap = parseAuthenticateHeader(authenticateHeader); String realm = parameterMap.get("realm"); + if (realm == null || realm.isEmpty()) { + throw new AuthenticationException(sm.getString("digestAuthenticator.noRealm")); + } validateRealm(userRealm, realm); diff --git a/java/org/apache/tomcat/websocket/LocalStrings.properties b/java/org/apache/tomcat/websocket/LocalStrings.properties index f5e0361538..24dfdca8f8 100644 --- a/java/org/apache/tomcat/websocket/LocalStrings.properties +++ b/java/org/apache/tomcat/websocket/LocalStrings.properties @@ -42,6 +42,7 @@ clientEndpointHolder.instanceRegistrationFailed=Failed to register Endpoint inst digestAuthenticator.algorithm=Unable to generate request digest [{0}] digestAuthenticator.noQop=The server challenge did not include a qop value +digestAuthenticator.noRealm=The server challenge did not include a realm value futureToSendHandler.timeout=Operation timed out after waiting [{0}] [{1}] to complete diff --git a/test/org/apache/tomcat/websocket/TestDigestAuthenticator.java b/test/org/apache/tomcat/websocket/TestDigestAuthenticator.java index 682c1973f4..de790d458b 100644 --- a/test/org/apache/tomcat/websocket/TestDigestAuthenticator.java +++ b/test/org/apache/tomcat/websocket/TestDigestAuthenticator.java @@ -42,6 +42,15 @@ public class TestDigestAuthenticator { doTestAuthorization("auth-int"); } + @Test(expected = AuthenticationException.class) + public void testAuthorizationMissingRealm() throws Exception { + String authenticateHeader = + "Digest qop=\"auth\", nonce=\"0000f844a605d5c0cb0270f1e2f10ca0\", algorithm=MD5"; + + DigestAuthenticator authenticator = new DigestAuthenticator(); + authenticator.getAuthorization("GET", "/ws/echo", authenticateHeader, "user", "password", null); + } + private void doTestAuthorization(String qop) throws Exception { String method = "GET"; String requestUri = "/ws/echo"; --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
