During a Web Security Assessment for one of our clients, we identified some abnormal behavior on the Single-Sign-On solution they were using: Red Hat’s Keycloak. After further investigation, we found a vulnerability that gave us the ability to impersonate other users.

After logging in into Keycloak with valid credentials, a call is made to /realms/{realm}/protocol/openid-connect/token which returns the JWTs of the user. In the call, here we can see that that call includes a POST parameter “code” consisting of three v4 UUIDs:

Code parameter on token request

We observed that only the first two UUIDs change between logins, while the third stays the same, even when logging in as different users. Also, the second identifier can also be found in previous requests, even before the login is initiated.

Apparently, the second UUID identifies a session, the third the realm of the login while the first identifies a valid login attempt.

Interestingly, we discovered that the first UUID is not linked in any way to the user logging in. Therefore, if we have a valid account, we can abuse this to impersonate a session to which we know the ID.

In order to do this, we have to start the logging in process normally with our user, intercept the call to /realms/{realm}/protocol/openid-connect/token and change the second UUID with the one from the user we want to impersonate:

Forged code parameter

This returns an access_token, refresh_token and id_token of the impersonated user:

Impersonated tokens

These tokens can then be used to steal the session and access the account of the impersonated user:

Stolen user account

In order to exploit this vulnerability, a valid account in the realm of the victim and a way to extract the second UUID of the code is required.

Since this code is sent to the user through one of the GET parameters in the URL referenced by the Location header found in the response of the login POST message, it could be leaked in many ways:

  • A shoulder surfing attack could be used to get the code from the url during the time it is shown on the address bar.
  • Extracted from the browser history.
  • Shared by accident by copying a url to share the website.
  • Sent on the Referer header when requesting resources to other websites.
  • Stored by analytics tools.

Since this UUID also appears on the AUTH_SESSION_ID and AUTH_SESSION_ID_LEGACY cookies, which are given even before login, this vulnerability could also be exploited through a session fixation attack, where an attacker with physical access to the computer would acquire this part of the code before the user logging in by checking the cookie.

The vulnerability was reported to Red Hat, which validated the vulnerability and assigned the following CVE:

The vulnerability was fixed in Keycloak version 21.0.1