[keycloak-user] Username enumeration

Gregoire Jeanmart Gregoire.Jeanmart at ai-london.com
Thu Oct 19 08:23:22 EDT 2017


Hello,

One of our customers ran a penetration tests on our platform which uses Keycloak as Identity & Access Management system.
The penetration result was good except a medium issue that could result a large discovery of usernames.

Let me explain the steps to reproduce this:
1. Login to the system with valid credentials

2. Copy the execution parameter [%EXECUTION%] from the POST authenticate HTTP request
https://%KEYCLOAK%/auth/realms/%REALM%/login-actions/authenticate?code=%CODE%&execution=%EXECUTION%&client_id=%CLIENT_ID%

3. Copy the AUTH_SESSION_ID cookie [%AUTH_SESSION_ID%] from the POST authenticate HTTP request

4. Execute the POST authenticate HTTP request again with the execution parameter %EXECUTION% and AUTH_SESSION_ID cookie %AUTH_SESSION_ID%
POST /auth/realms/%REALM%/login-actions/authenticate?code=%CODE%&execution=%EXECUTION%&client_id=%CLIENT_ID% HTTP/1.1
Content-Type: application/x-www-form-urlencoded
Cookie: AUTH_SESSION_ID=%AUTH_SESSION_ID%
Cache-Control: no-cache

Body: username=%USERNAME%&password=123&login=Log+in

5. From the HTML response (Invalid username or password) extract the code %CODE% (because unique) from the form action
      <div id="kc-form" class="col-xs-12 col-sm-12 col-md-12 col-lg-12 login">
            <div id="kc-form-wrapper" class="">
                  <form id="kc-form-login" class="form-horizontal" action="https://%KEYCLOAK/auth/realms/%REALM%/login-actions/authenticate?code=%CODE%&execution=%EXECUTION&client_id=%CLIENT_ID%" method="post">
                        <div class="form-group">
                              <div class="col-xs-12 col-sm-12 col-md-4 col-lg-3">
                                    <label for="username" class="control-label">Username</label>

6. Replay the step 4 and 5 and change the username in the body part.


We can then distinguish a pattern:
- Screenshot: https://imgur.com/a/pwtPH
If the user is an existing username, the response time 3 - 4 time longer than if the user doesn't existing (whatever the password). So with this method I could enumerate all the usernames in the system using a dictionary and a brute force attack.

The Keycloak Brute Force Attack detection doesn't prevent this as it only locks out user for a given username.

Ideal solution:
If Keycloak could prevent this behaviour by making sure the elapsed time of computation for login in is approximately the same for an existing or non-existing user.

Alternative Solutions:
Alternative solution is to use fail2ban to block an IP when this kind of behaviour is detected.

Thanks.

Gregoire Jeanmart



More information about the keycloak-user mailing list