A privilege escalation flaw was found in the token exchange feature of keycloak. Missing authorization allows a client application holding a valid access token to exchange tokens for any target client by passing the client_id of the target. This could allow a client to gain unauthorized access to additional services.
Keycloak supports OAuth2 Token Exchange an OAuth2 specification that allows clients to exchange tokens for delegation and impersonation purposes.
In Keycloak, the support for token exchange is marked as a technology preview feature and disabled by default.
When the feature is enabled, any client application holding a valid access token is able to exchange tokens for any other target client by authenticating as the target client. This problem is especially problematic when the credentials used to authenticate to the token endpoint is for a public client because the authentication for these clients is solely based on the client_id (public information).
The vulnerability found allows a malicious client to exchange tokens for another client and then use the new token to access services that otherwise it should not have access.
The expected behavior should be that clients (regardless of public or confidential) should only be able to exchange tokens for themselves, and using a subject_token issued to another client should be prohibited if there is no permission granted.
To reproduce the issue:
1. The preview feature token-exchange must be enabled. Given 1 user, 1
public or secret client (client-third-party) in which an attacker has
access to, and 1 public client (client-secure) in the same realm.
2. Assume client-third-party is a restricted client and has no realm or
resource access. The public client, client-secure, has access to an
API secured with a resource access role.
3. Authenticate as a user with the client-third-party client and store
the user's access token
4. Use the access token in a token exchange request. Specify
client-secure as client_id, the user's access token as subject_token
and do not add an audience parameter.
5. The result of the token exchange will be an access token, and
potentially a refresh token, with all access which only the
client-secure should have access to.
Notice that in order to reproduce this, you do not have to configure
any permissions for the client. Neither do you have to enable the
admin fine grained permissions feature.
Keycloak supports OAuth2 Token Exchange an OAuth2 specification that allows clients to exchange tokens for delegation and impersonation purposes. In Keycloak, the support for token exchange is marked as a technology preview feature and disabled by default. When the feature is enabled, any client application holding a valid access token is able to exchange tokens for any other target client by authenticating as the target client. This problem is especially problematic when the credentials used to authenticate to the token endpoint is for a public client because the authentication for these clients is solely based on the client_id (public information). The vulnerability found allows a malicious client to exchange tokens for another client and then use the new token to access services that otherwise it should not have access. The expected behavior should be that clients (regardless of public or confidential) should only be able to exchange tokens for themselves, and using a subject_token issued to another client should be prohibited if there is no permission granted. To reproduce the issue: 1. The preview feature token-exchange must be enabled. Given 1 user, 1 public or secret client (client-third-party) in which an attacker has access to, and 1 public client (client-secure) in the same realm. 2. Assume client-third-party is a restricted client and has no realm or resource access. The public client, client-secure, has access to an API secured with a resource access role. 3. Authenticate as a user with the client-third-party client and store the user's access token 4. Use the access token in a token exchange request. Specify client-secure as client_id, the user's access token as subject_token and do not add an audience parameter. 5. The result of the token exchange will be an access token, and potentially a refresh token, with all access which only the client-secure should have access to. Notice that in order to reproduce this, you do not have to configure any permissions for the client. Neither do you have to enable the admin fine grained permissions feature.