CVE-2025-11429
Description
A flaw was found in Keycloak. Keycloak does not immediately enforce the disabling of the "Remember Me" realm setting on existing user sessions. Sessions created while "Remember Me" was active retain their extended session lifetime until they expire, overriding the administrator's recent security configuration change. This is a logic flaw in session management increases the potential window for successful session hijacking or unauthorized long-term access persistence. The flaw lies in the session expiration logic relying on the session-local "remember-me" flag without validating the current realm-level configuration.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
org.keycloak:keycloak-servicesMaven | >= 26.3.0, < 26.4.1 | 26.4.1 |
org.keycloak:keycloak-servicesMaven | < 26.2.11 | 26.2.11 |
Affected products
1Patches
3a34094100716Invalidate sessions created with remember me when remember me is disabled for realm
6 files changed · +64 −8
docs/documentation/server_admin/topics/login-settings/remember-me.adoc+2 −0 modified@@ -16,3 +16,5 @@ When you save this setting, a `remember me` checkbox displays on the realm's log .Remember Me image:images/remember-me.png[Remember Me] +WARNING: Note that disabling the "Remember me" option will invalidate all sessions created with the "Remember me" checkbox selected during login, requiring users to log in again. Any refresh tokens related to these sessions will also become invalid. +Note also that the sessions will not be invalidated immediately when the switch is disabled, but only when a cookie or token associated with an invalid session is used. This means that disabling and then re-enabling the "Remember me" switch cannot be used to invalidate old sessions.
docs/documentation/upgrading/topics/changes/changes-26_4_1.adoc+10 −0 added@@ -0,0 +1,10 @@ +// ------------------------ Notable changes ------------------------ // +== Notable changes + +Notable changes where an internal behavior changed to prevent common misconfigurations, fix bugs or simplify running {project_name}. + +=== User sessions created with "Remember Me" are no longer valid if "Remember Me" is disabled for the realm + +When the "Remember Me" option is disabled in the realm settings, all user sessions previously created with the "Remember Me" flag are now considered invalid. +Users will be required to log in again, and any associated refresh tokens will no longer be usable. +User sessions created without selecting "Remember Me" are not affected.
js/apps/admin-ui/maven-resources/theme/keycloak.v2/admin/messages/messages_en.properties+1 −1 modified@@ -1820,7 +1820,7 @@ groupUpdateError=Error updating group {{error}} logoutAllSessions=Logout all sessions membershipUserLdapAttribute=Membership user LDAP attribute noKeysDescription=You haven't created any active keys -rememberMeHelpText=Show checkbox on the login page to allow the user to remain logged in between browser restarts until the session expires. +rememberMeHelpText=Show checkbox on the login page to allow the user to remain logged in between browser restarts until the session expires. If disabled, all sessions created with the "Remember me" checkbox selected during login are considered invalid. eventTypes.UPDATE_EMAIL.name=Update email notBeforeHelp=Revoke any tokens issued before this time for this client. To push the policy, you should set an effective admin URL in the Settings tab first. protocolTypes.saml=SAML
services/src/main/java/org/keycloak/services/managers/AuthenticationManager.java+4 −0 modified@@ -185,6 +185,10 @@ public static boolean isSessionValid(RealmModel realm, UserSessionModel userSess logger.debug("No user session"); return false; } + if (userSession.isRememberMe() && !realm.isRememberMe()) { + logger.debugv("Session {0} invalid: created with remember me but remember me is disabled for the realm.", userSession.getId()); + return false; + } if (userSession.getNote(Details.IDENTITY_PROVIDER) != null) { String brokerAlias = userSession.getNote(Details.IDENTITY_PROVIDER); if (realm.getIdentityProviderByAlias(brokerAlias) == null) {
testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/LoginTest.java+46 −6 modified@@ -71,6 +71,7 @@ import org.keycloak.testsuite.util.ContainerAssume; import org.keycloak.testsuite.util.InfinispanTestTimeServiceRule; import org.keycloak.testsuite.util.Matchers; +import org.keycloak.testsuite.util.oauth.AccessTokenResponse; import org.keycloak.testsuite.util.oauth.OAuthClient; import org.keycloak.testsuite.util.RealmBuilder; import org.keycloak.testsuite.util.TokenSignatureUtil; @@ -86,6 +87,8 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotEquals; import static org.hamcrest.MatcherAssert.assertThat; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.keycloak.common.Profile.Feature.DYNAMIC_SCOPES; import static org.keycloak.testsuite.admin.ApiUtil.findClientByClientId; @@ -170,7 +173,7 @@ public void testBrowserSecurityHeaders() { String headerValue = response.getHeaderString(header.getHeaderName()); String expectedValue = header.getDefaultValue(); if (expectedValue.isEmpty()) { - Assert.assertNull(headerValue); + assertNull(headerValue); } else { Assert.assertNotNull(headerValue); assertThat(headerValue, is(equalTo(expectedValue))); @@ -252,7 +255,7 @@ public void loginChangeUserAfterInvalidPassword() { Assert.assertEquals("", loginPage.getPassword()); Assert.assertEquals("Invalid username or password.", loginPage.getUsernameInputError()); - Assert.assertNull(loginPage.getPasswordInputError()); + assertNull(loginPage.getPasswordInputError()); events.expectLogin().user(user2Id).session((String) null).error("invalid_user_credentials") .detail(Details.USERNAME, "login-test2") @@ -279,7 +282,7 @@ public void loginInvalidPassword() { Assert.assertEquals("", loginPage.getPassword()); Assert.assertEquals("Invalid username or password.", loginPage.getUsernameInputError()); - Assert.assertNull(loginPage.getPasswordInputError()); + assertNull(loginPage.getPasswordInputError()); events.expectLogin().user(userId).session((String) null).error("invalid_user_credentials") .detail(Details.USERNAME, "login-test") @@ -299,7 +302,7 @@ public void loginMissingPassword() { Assert.assertEquals("", loginPage.getPassword()); Assert.assertEquals("Invalid username or password.", loginPage.getUsernameInputError()); - Assert.assertNull(loginPage.getPasswordInputError()); + assertNull(loginPage.getPasswordInputError()); events.expectLogin().user(userId).session((String) null).error("invalid_user_credentials") .detail(Details.USERNAME, "login-test") @@ -683,7 +686,7 @@ public void loginWithRememberMeNotSet() { .detail(Details.USERNAME, "login-test") .assertEvent(); // check remember me is not set although it was sent in the form data - Assert.assertNull(loginEvent.getDetails().get(Details.REMEMBER_ME)); + assertNull(loginEvent.getDetails().get(Details.REMEMBER_ME)); } //KEYCLOAK-2741 @@ -769,6 +772,43 @@ public void loginWithEmailUserAndRememberMe() { } } + @Test + public void testLoginAfterDisablingRememberMeInRealmSettings() { + setRememberMe(true); + + try { + //login with remember me + loginPage.open(); + loginPage.setRememberMe(true); + assertTrue(loginPage.isRememberMeChecked()); + loginPage.login("login@test.com", getPassword("login-test")); + + Assert.assertEquals(RequestType.AUTH_RESPONSE, appPage.getRequestType()); + Assert.assertNotNull(oauth.parseLoginResponse().getCode()); + events.expectLogin().user(userId) + .detail(Details.USERNAME, "login@test.com") + .detail(Details.REMEMBER_ME, "true") + .assertEvent(); + + AccessTokenResponse response = oauth.accessTokenRequest(oauth.parseLoginResponse().getCode()).send(); + + setRememberMe(false); + + //refresh fail + response = oauth.refreshRequest(response.getRefreshToken()).send(); + assertNull(response.getAccessToken()); + assertNotNull(response.getError()); + assertEquals("Session not active", response.getErrorDescription()); + + // Assert session removed + loginPage.open(); + assertFalse(loginPage.isRememberMeCheckboxPresent()); + assertNotEquals("login-test", loginPage.getUsername()); + } finally { + setRememberMe(false); + } + } + // Login timeout scenarios // KEYCLOAK-1037 @Test @@ -892,7 +932,7 @@ public void openLoginFormAfterExpiredCode() throws Exception { oauth.openLoginForm(); loginPage.assertCurrent(); - Assert.assertNull("Not expected to have error on loginForm.", loginPage.getError()); + assertNull("Not expected to have error on loginForm.", loginPage.getError()); loginPage.login("test-user@localhost", getPassword("test-user@localhost")); appPage.assertCurrent();
testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/session/SessionTimeoutValidationTest.java+1 −1 modified@@ -75,7 +75,7 @@ public void testIsSessionValid(KeycloakSession session) { session.sessions().createUserSession( null, realm, session.users().getUserByUsername(realm, "user1"), - "user1", "127.0.0.1", "form", true, null, null, + "user1", "127.0.0.1", "form", false, null, null, UserSessionModel.SessionPersistenceState.PERSISTENT); realm.setSsoSessionIdleTimeout(Integer.MAX_VALUE);
bda0e2a67c8cInvalidate sessions created with remember me when remember me is disabled for realm
6 files changed · +60 −8
docs/documentation/server_admin/topics/login-settings/remember-me.adoc+2 −0 modified@@ -16,3 +16,5 @@ When you save this setting, a `remember me` checkbox displays on the realm's log .Remember Me image:images/remember-me.png[Remember Me] +WARNING: Note that disabling the "Remember me" option will invalidate all sessions created with the "Remember me" checkbox selected during login, requiring users to log in again. Any refresh tokens related to these sessions will also become invalid. +Note also that the sessions will not be invalidated immediately when the switch is disabled, but only when a cookie or token associated with an invalid session is used. This means that disabling and then re-enabling the "Remember me" switch cannot be used to invalidate old sessions.
docs/documentation/upgrading/topics/changes/changes-26_5_0.adoc+6 −0 modified@@ -12,6 +12,12 @@ The `log-console-color` previously defaulted to `false`, but it will now instead You may still explicitly disable color support by setting the option to `false`. +=== User sessions created with "Remember Me" are no longer valid if "Remember Me" is disabled for the realm + +When the "Remember Me" option is disabled in the realm settings, all user sessions previously created with the "Remember Me" flag are now considered invalid. +Users will be required to log in again, and any associated refresh tokens will no longer be usable. +User sessions created without selecting "Remember Me" are not affected. + // ------------------------ Deprecated features ------------------------ // == Deprecated features
js/apps/admin-ui/maven-resources/theme/keycloak.v2/admin/messages/messages_en.properties+1 −1 modified@@ -1821,7 +1821,7 @@ groupUpdateError=Error updating group {{error}} logoutAllSessions=Logout all sessions membershipUserLdapAttribute=Membership user LDAP attribute noKeysDescription=You haven't created any active keys -rememberMeHelpText=Show checkbox on the login page to allow the user to remain logged in between browser restarts until the session expires. +rememberMeHelpText=Show checkbox on the login page to allow the user to remain logged in between browser restarts until the session expires. If disabled, all sessions created with the "Remember me" checkbox selected during login are considered invalid. eventTypes.UPDATE_EMAIL.name=Update email notBeforeHelp=Revoke any tokens issued before this time for this client. To push the policy, you should set an effective admin URL in the Settings tab first. protocolTypes.saml=SAML
services/src/main/java/org/keycloak/services/managers/AuthenticationManager.java+4 −0 modified@@ -185,6 +185,10 @@ public static boolean isSessionValid(RealmModel realm, UserSessionModel userSess logger.debug("No user session"); return false; } + if (userSession.isRememberMe() && !realm.isRememberMe()) { + logger.debugv("Session {0} invalid: created with remember me but remember me is disabled for the realm.", userSession.getId()); + return false; + } if (userSession.getNote(Details.IDENTITY_PROVIDER) != null) { String brokerAlias = userSession.getNote(Details.IDENTITY_PROVIDER); if (realm.getIdentityProviderByAlias(brokerAlias) == null) {
testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/LoginTest.java+46 −6 modified@@ -71,6 +71,7 @@ import org.keycloak.testsuite.util.ContainerAssume; import org.keycloak.testsuite.util.InfinispanTestTimeServiceRule; import org.keycloak.testsuite.util.Matchers; +import org.keycloak.testsuite.util.oauth.AccessTokenResponse; import org.keycloak.testsuite.util.oauth.OAuthClient; import org.keycloak.testsuite.util.RealmBuilder; import org.keycloak.testsuite.util.TokenSignatureUtil; @@ -86,6 +87,8 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotEquals; import static org.hamcrest.MatcherAssert.assertThat; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.keycloak.common.Profile.Feature.DYNAMIC_SCOPES; import static org.keycloak.testsuite.admin.ApiUtil.findClientByClientId; @@ -170,7 +173,7 @@ public void testBrowserSecurityHeaders() { String headerValue = response.getHeaderString(header.getHeaderName()); String expectedValue = header.getDefaultValue(); if (expectedValue.isEmpty()) { - Assert.assertNull(headerValue); + assertNull(headerValue); } else { Assert.assertNotNull(headerValue); assertThat(headerValue, is(equalTo(expectedValue))); @@ -252,7 +255,7 @@ public void loginChangeUserAfterInvalidPassword() { Assert.assertEquals("", loginPage.getPassword()); Assert.assertEquals("Invalid username or password.", loginPage.getUsernameInputError()); - Assert.assertNull(loginPage.getPasswordInputError()); + assertNull(loginPage.getPasswordInputError()); events.expectLogin().user(user2Id).session((String) null).error("invalid_user_credentials") .detail(Details.USERNAME, "login-test2") @@ -279,7 +282,7 @@ public void loginInvalidPassword() { Assert.assertEquals("", loginPage.getPassword()); Assert.assertEquals("Invalid username or password.", loginPage.getUsernameInputError()); - Assert.assertNull(loginPage.getPasswordInputError()); + assertNull(loginPage.getPasswordInputError()); events.expectLogin().user(userId).session((String) null).error("invalid_user_credentials") .detail(Details.USERNAME, "login-test") @@ -299,7 +302,7 @@ public void loginMissingPassword() { Assert.assertEquals("", loginPage.getPassword()); Assert.assertEquals("Invalid username or password.", loginPage.getUsernameInputError()); - Assert.assertNull(loginPage.getPasswordInputError()); + assertNull(loginPage.getPasswordInputError()); events.expectLogin().user(userId).session((String) null).error("invalid_user_credentials") .detail(Details.USERNAME, "login-test") @@ -683,7 +686,7 @@ public void loginWithRememberMeNotSet() { .detail(Details.USERNAME, "login-test") .assertEvent(); // check remember me is not set although it was sent in the form data - Assert.assertNull(loginEvent.getDetails().get(Details.REMEMBER_ME)); + assertNull(loginEvent.getDetails().get(Details.REMEMBER_ME)); } //KEYCLOAK-2741 @@ -769,6 +772,43 @@ public void loginWithEmailUserAndRememberMe() { } } + @Test + public void testLoginAfterDisablingRememberMeInRealmSettings() { + setRememberMe(true); + + try { + //login with remember me + loginPage.open(); + loginPage.setRememberMe(true); + assertTrue(loginPage.isRememberMeChecked()); + loginPage.login("login@test.com", getPassword("login-test")); + + Assert.assertEquals(RequestType.AUTH_RESPONSE, appPage.getRequestType()); + Assert.assertNotNull(oauth.parseLoginResponse().getCode()); + events.expectLogin().user(userId) + .detail(Details.USERNAME, "login@test.com") + .detail(Details.REMEMBER_ME, "true") + .assertEvent(); + + AccessTokenResponse response = oauth.accessTokenRequest(oauth.parseLoginResponse().getCode()).send(); + + setRememberMe(false); + + //refresh fail + response = oauth.refreshRequest(response.getRefreshToken()).send(); + assertNull(response.getAccessToken()); + assertNotNull(response.getError()); + assertEquals("Session not active", response.getErrorDescription()); + + // Assert session removed + loginPage.open(); + assertFalse(loginPage.isRememberMeCheckboxPresent()); + assertNotEquals("login-test", loginPage.getUsername()); + } finally { + setRememberMe(false); + } + } + // Login timeout scenarios // KEYCLOAK-1037 @Test @@ -892,7 +932,7 @@ public void openLoginFormAfterExpiredCode() throws Exception { oauth.openLoginForm(); loginPage.assertCurrent(); - Assert.assertNull("Not expected to have error on loginForm.", loginPage.getError()); + assertNull("Not expected to have error on loginForm.", loginPage.getError()); loginPage.login("test-user@localhost", getPassword("test-user@localhost")); appPage.assertCurrent();
testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/session/SessionTimeoutValidationTest.java+1 −1 modified@@ -75,7 +75,7 @@ public void testIsSessionValid(KeycloakSession session) { session.sessions().createUserSession( null, realm, session.users().getUserByUsername(realm, "user1"), - "user1", "127.0.0.1", "form", true, null, null, + "user1", "127.0.0.1", "form", false, null, null, UserSessionModel.SessionPersistenceState.PERSISTENT); realm.setSsoSessionIdleTimeout(Integer.MAX_VALUE);
a752492843e2Invalidate sessions created with remember me when remember me is disabled for realm
7 files changed · +68 −8
docs/documentation/server_admin/topics/login-settings/remember-me.adoc+2 −0 modified@@ -16,3 +16,5 @@ When you save this setting, a `remember me` checkbox displays on the realm's log .Remember Me image:images/remember-me.png[Remember Me] +WARNING: Note that disabling the "Remember me" option will invalidate all sessions created with the "Remember me" checkbox selected during login, requiring users to log in again. Any refresh tokens related to these sessions will also become invalid. +Note also that the sessions will not be invalidated immediately when the switch is disabled, but only when a cookie or token associated with an invalid session is used. This means that disabling and then re-enabling the "Remember me" switch cannot be used to invalidate old sessions.
docs/documentation/upgrading/topics/changes/changes-26_2_11.adoc+10 −0 added@@ -0,0 +1,10 @@ +// ------------------------ Notable changes ------------------------ // +== Notable changes + +Notable changes where an internal behavior changed to prevent common misconfigurations, fix bugs or simplify running {project_name}. + +=== User sessions created with "Remember Me" are no longer valid if "Remember Me" is disabled for the realm + +When the "Remember Me" option is disabled in the realm settings, all user sessions previously created with the "Remember Me" flag are now considered invalid. +Users will be required to log in again, and any associated refresh tokens will no longer be usable. +User sessions created without selecting "Remember Me" are not affected.
docs/documentation/upgrading/topics/changes/changes.adoc+4 −0 modified@@ -1,6 +1,10 @@ [[migration-changes]] == Migration Changes +=== Migrating to 26.2.11 + +include::changes-26_2_11.adoc[leveloffset=2] + === Migrating to 26.2.10 include::changes-26_2_10.adoc[leveloffset=2]
js/apps/admin-ui/maven-resources/theme/keycloak.v2/admin/messages/messages_en.properties+1 −1 modified@@ -1791,7 +1791,7 @@ groupUpdateError=Error updating group {{error}} logoutAllSessions=Logout all sessions membershipUserLdapAttribute=Membership user LDAP attribute noKeysDescription=You haven't created any active keys -rememberMeHelpText=Show checkbox on the login page to allow the user to remain logged in between browser restarts until the session expires. +rememberMeHelpText=Show checkbox on the login page to allow the user to remain logged in between browser restarts until the session expires. If disabled, all sessions created with the "Remember me" checkbox selected during login are considered invalid. eventTypes.UPDATE_EMAIL.name=Update email notBeforeHelp=Revoke any tokens issued before this time for this client. To push the policy, you should set an effective admin URL in the Settings tab first. protocolTypes.saml=SAML
services/src/main/java/org/keycloak/services/managers/AuthenticationManager.java+4 −0 modified@@ -187,6 +187,10 @@ public static boolean isSessionValid(RealmModel realm, UserSessionModel userSess logger.debug("No user session"); return false; } + if (userSession.isRememberMe() && !realm.isRememberMe()) { + logger.debugv("Session {0} invalid: created with remember me but remember me is disabled for the realm.", userSession.getId()); + return false; + } if (userSession.getNote(Details.IDENTITY_PROVIDER) != null) { String brokerAlias = userSession.getNote(Details.IDENTITY_PROVIDER); if (realm.getIdentityProviderByAlias(brokerAlias) == null) {
testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/LoginTest.java+46 −6 modified@@ -71,6 +71,7 @@ import org.keycloak.testsuite.util.ContainerAssume; import org.keycloak.testsuite.util.InfinispanTestTimeServiceRule; import org.keycloak.testsuite.util.Matchers; +import org.keycloak.testsuite.util.oauth.AccessTokenResponse; import org.keycloak.testsuite.util.oauth.OAuthClient; import org.keycloak.testsuite.util.RealmBuilder; import org.keycloak.testsuite.util.TokenSignatureUtil; @@ -86,6 +87,8 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotEquals; import static org.hamcrest.MatcherAssert.assertThat; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.keycloak.common.Profile.Feature.DYNAMIC_SCOPES; import static org.keycloak.testsuite.admin.ApiUtil.findClientByClientId; @@ -170,7 +173,7 @@ public void testBrowserSecurityHeaders() { String headerValue = response.getHeaderString(header.getHeaderName()); String expectedValue = header.getDefaultValue(); if (expectedValue.isEmpty()) { - Assert.assertNull(headerValue); + assertNull(headerValue); } else { Assert.assertNotNull(headerValue); assertThat(headerValue, is(equalTo(expectedValue))); @@ -252,7 +255,7 @@ public void loginChangeUserAfterInvalidPassword() { Assert.assertEquals("", loginPage.getPassword()); Assert.assertEquals("Invalid username or password.", loginPage.getUsernameInputError()); - Assert.assertNull(loginPage.getPasswordInputError()); + assertNull(loginPage.getPasswordInputError()); events.expectLogin().user(user2Id).session((String) null).error("invalid_user_credentials") .detail(Details.USERNAME, "login-test2") @@ -279,7 +282,7 @@ public void loginInvalidPassword() { Assert.assertEquals("", loginPage.getPassword()); Assert.assertEquals("Invalid username or password.", loginPage.getUsernameInputError()); - Assert.assertNull(loginPage.getPasswordInputError()); + assertNull(loginPage.getPasswordInputError()); events.expectLogin().user(userId).session((String) null).error("invalid_user_credentials") .detail(Details.USERNAME, "login-test") @@ -299,7 +302,7 @@ public void loginMissingPassword() { Assert.assertEquals("", loginPage.getPassword()); Assert.assertEquals("Invalid username or password.", loginPage.getUsernameInputError()); - Assert.assertNull(loginPage.getPasswordInputError()); + assertNull(loginPage.getPasswordInputError()); events.expectLogin().user(userId).session((String) null).error("invalid_user_credentials") .detail(Details.USERNAME, "login-test") @@ -683,7 +686,7 @@ public void loginWithRememberMeNotSet() { .detail(Details.USERNAME, "login-test") .assertEvent(); // check remember me is not set although it was sent in the form data - Assert.assertNull(loginEvent.getDetails().get(Details.REMEMBER_ME)); + assertNull(loginEvent.getDetails().get(Details.REMEMBER_ME)); } //KEYCLOAK-2741 @@ -769,6 +772,43 @@ public void loginWithEmailUserAndRememberMe() { } } + @Test + public void testLoginAfterDisablingRememberMeInRealmSettings() { + setRememberMe(true); + + try { + //login with remember me + loginPage.open(); + loginPage.setRememberMe(true); + assertTrue(loginPage.isRememberMeChecked()); + loginPage.login("login@test.com", getPassword("login-test")); + + Assert.assertEquals(RequestType.AUTH_RESPONSE, appPage.getRequestType()); + Assert.assertNotNull(oauth.parseLoginResponse().getCode()); + events.expectLogin().user(userId) + .detail(Details.USERNAME, "login@test.com") + .detail(Details.REMEMBER_ME, "true") + .assertEvent(); + + AccessTokenResponse response = oauth.accessTokenRequest(oauth.parseLoginResponse().getCode()).send(); + + setRememberMe(false); + + //refresh fail + response = oauth.refreshRequest(response.getRefreshToken()).send(); + assertNull(response.getAccessToken()); + assertNotNull(response.getError()); + assertEquals("Session not active", response.getErrorDescription()); + + // Assert session removed + loginPage.open(); + assertFalse(loginPage.isRememberMeCheckboxPresent()); + assertNotEquals("login-test", loginPage.getUsername()); + } finally { + setRememberMe(false); + } + } + // Login timeout scenarios // KEYCLOAK-1037 @Test @@ -892,7 +932,7 @@ public void openLoginFormAfterExpiredCode() throws Exception { oauth.openLoginForm(); loginPage.assertCurrent(); - Assert.assertNull("Not expected to have error on loginForm.", loginPage.getError()); + assertNull("Not expected to have error on loginForm.", loginPage.getError()); loginPage.login("test-user@localhost", getPassword("test-user@localhost")); appPage.assertCurrent();
testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/session/SessionTimeoutValidationTest.java+1 −1 modified@@ -75,7 +75,7 @@ public void testIsSessionValid(KeycloakSession session) { session.sessions().createUserSession( null, realm, session.users().getUserByUsername(realm, "user1"), - "user1", "127.0.0.1", "form", true, null, null, + "user1", "127.0.0.1", "form", false, null, null, UserSessionModel.SessionPersistenceState.PERSISTENT); realm.setSsoSessionIdleTimeout(Integer.MAX_VALUE);
Vulnerability mechanics
Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
10- github.com/advisories/GHSA-64w3-5q9m-68xfghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2025-11429ghsaADVISORY
- access.redhat.com/errata/RHSA-2025:22088nvdWEB
- access.redhat.com/errata/RHSA-2025:22089nvdWEB
- access.redhat.com/security/cve/CVE-2025-11429nvdWEB
- bugzilla.redhat.com/show_bug.cginvdWEB
- github.com/keycloak/keycloak/commit/a34094100716b7c69ae38eaed6678ab4344d0a1dnvdWEB
- github.com/keycloak/keycloak/commit/a752492843e21c3ab06090616692e53001864158ghsaWEB
- github.com/keycloak/keycloak/commit/bda0e2a67c8cf41d1b3d9010e6dfcddaf79bf59bnvdWEB
- github.com/keycloak/keycloak/issues/43328nvdWEB
News mentions
0No linked articles in our index yet.