This is an automated email from the ASF dual-hosted git repository.

rmaucher pushed a commit to branch 11.0.x
in repository https://gitbox.apache.org/repos/asf/tomcat.git

commit 2809b1d8c26a223229df6ce326935b01bb1b8c36
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 f174c470fd..c28886eee5 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,14 +86,19 @@ public class CallbackHandlerImpl implements 
CallbackHandler, Contained {
                 } else if (callback instanceof PasswordValidationCallback) {
                     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 {
                         PasswordValidationCallback pvc = 
(PasswordValidationCallback) callback;
                         principal =
                                 
container.getRealm().authenticate(pvc.getUsername(), 
String.valueOf(pvc.getPassword()));
                         pvc.setResult(principal != null);
+                        if (principal == null) {
+                            passwordValidationFailed = true;
+                        }
                         subject = pvc.getSubject();
                     }
                 } else {
@@ -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