GET /user endpoint returns `enabled=true` even though the user is locked due to brute force attack

Solution Verified - Updated -

Environment

  • Red Hat Single Sign-On (RH-SSO)
    • 7.x

Issue

  • When the user is locked temporarily due to brute force attack, GET /user endpoint still returns enabled=true for the user

Resolution

  • The behavior is as per design. To introduce a new attribute like temporarilyDisabled will be an enhancement request.

  • There is a ongoing discussion, consideration from different aspect like significant impact on performance. If the discussion will be
    positive for changes, then the enhancement might be included in later version of RH-SSO.

https://github.com/keycloak/keycloak/issues/11726
https://github.com/keycloak/keycloak/pull/8432
https://issues.redhat.com/browse/KEYCLOAK-19273
  • A possible workaround is to call any other API which considers enabled attribute from cache.
#Get status of a username in brute force detection : 
GET /{realm}/attack-detection/brute-force/users/{userId}

OR 

#Get representation of the user
GET /{realm}/users/{id}

Root Cause

  • When brute force attack is detected, enabled attribute of a user profile object on memory is set to false. It does not update the user profile in the database. On the other hand, GET /users API refers to the DB. Hence the enabled attribute returns as true even after user is locked temporarily due to brute force attack.

    • A user profile object on memory is an instance of org.keycloak.representations.idm.UserRepresentation. Its "enabled" is set at the line 283 of org.keycloak.services.resources.admin.UserResource.getUser():
272     public UserRepresentation getUser() {
273         auth.users().requireView(user);
274 
275         UserRepresentation rep = ModelToRepresentation.toRepresentation(session, realm, user);
276 
277         if (realm.isIdentityFederationEnabled()) {
278             List<FederatedIdentityRepresentation> reps = getFederatedIdentities(user).collect(Collectors.toList());
279             rep.setFederatedIdentities(reps);
280         }
281 
282         if (session.getProvider(BruteForceProtector.class).isTemporarilyDisabled(session, realm, user)) {
283             rep.setEnabled(false);   <===HERE
284         }

This solution is part of Red Hat’s fast-track publication program, providing a huge library of solutions that Red Hat engineers have created while supporting our customers. To give you the knowledge you need the instant it becomes available, these articles may be presented in a raw and unedited form.

Comments