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 87ed9d47d4452ea32fc60c0287d18e19b731d11a
Author: opencode <[email protected]>
AuthorDate: Wed Sep 30 10:24:46 2026 +0200

    Update the JASPIC client Subject only when password validation succeeded 
(or was not requested), failing closed rather than adding a principal derived 
from untrusted caller-supplied data when validation failed
---
 .../catalina/authenticator/jaspic/CallbackHandlerImpl.java | 14 ++++++++++++--
 1 file changed, 12 insertions(+), 2 deletions(-)

diff --git 
a/java/org/apache/catalina/authenticator/jaspic/CallbackHandlerImpl.java 
b/java/org/apache/catalina/authenticator/jaspic/CallbackHandlerImpl.java
index 265cc01a58..19983df626 100644
--- a/java/org/apache/catalina/authenticator/jaspic/CallbackHandlerImpl.java
+++ b/java/org/apache/catalina/authenticator/jaspic/CallbackHandlerImpl.java
@@ -64,6 +64,7 @@ public class CallbackHandlerImpl implements CallbackHandler, 
Contained {
         Principal principal = null;
         Subject subject = null;
         String[] groups = null;
+        boolean passwordValidationFailed = false;
 
         if (callbacks != null) {
             /*
@@ -85,13 +86,18 @@ public class CallbackHandlerImpl implements 
CallbackHandler, Contained {
                         if (container == null) {
                             
log.warn(sm.getString("callbackHandlerImpl.containerMissing",
                                     callback.getClass().getName()));
+                            passwordValidationFailed = true;
                         } else if (container.getRealm() == null) {
                             
log.warn(sm.getString("callbackHandlerImpl.realmMissing", 
callback.getClass().getName(),
                                     container.getName()));
+                            passwordValidationFailed = true;
                         } else {
                             principal = 
container.getRealm().authenticate(pvc.getUsername(),
                                     String.valueOf(pvc.getPassword()));
                             pvc.setResult(principal != null);
+                            if (principal == null) {
+                                passwordValidationFailed = true;
+                            }
                             subject = pvc.getSubject();
                         }
                     }
@@ -100,8 +106,12 @@ public class CallbackHandlerImpl implements 
CallbackHandler, Contained {
                 }
             }
 
-            // If subject is null, there is nothing to do
-            if (subject != null) {
+            /*
+             * If subject is null, there is nothing to do. If password 
validation was requested and failed, do not
+             * update the subject. The Jakarta Authentication specification 
requires the runtime to update the subject
+             * only if authentication succeeds and, for security, the handler 
must fail closed.
+             */
+            if (subject != null && !passwordValidationFailed) {
 
                 // Need a name to create a Principal
                 if (name == null && principal != null) {


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to