
Keycloak est une solution open source de gestion des identités et des accès (IAM) qui permet de gérer l’authentification, l’autorisation et le contrôle des utilisateurs pour des applications et services grâce à des standards comme OAuth 2.0, OpenID Connect et SAML.
Le 19 août 2026 à 7:17 (heure de Paris), une vulnérabilité dans le service de réinitialisation de mot de passe de Keycloak a été communiquée publiquement sur le dépôt Github du projet, sous la référence CVE-2026-18963 (issue #51833). Cette vulnérabilité permet à un attaquant non authentifié de forcer la réinitialisation de mot de passe d’un utilisateur, sans avoir à cliquer sur le lien de vérification envoyé par mail. L’attaquant prend alors le contrôle total du compte de la victime en définissant un nouveau mot de passe. Cette vulnérabilité est pour le moment classée critique avec un score CVSS de 9.1 en raison de son impact et de sa facilité d’exploitation.
Conditions de vulnérabilité
Pour être vulnérable, une instance de Keycloak doit avoir un realm avec la fonctionnalité de réinitialisation de mot de passe activée, aussi appelée "Forgot Password". Cette fonctionnalité se trouve dans les paramètres du Realm dans Realm Settings > Login.

Exemple de configuration vulnérable
La vulnérabilité n'est présente qu'à partir de la version 26 et est en partie patchée, les versions vulnérables sont les suivantes :

Explication de la vulnérabilité
La vulnérabilité réside dans le flux reset-credentials, flux utilisé par défaut dans Keycloak lorsqu'on active la fonctionnalité de réinitialisation de mot de passe.
Deux failles chaînées, non exploitables seules, sont à l'origine de la vulnérabilité.
La première faille se trouve dans l'implémentation du flux d'authentification par défaut : services/src/main/java/org/keycloak/authentication/DefaultAuthenticationFlow.java
Où pour toute requête POST sur un endpoint du service d'authentification qui défini le paramètre tryAnotherWay, le code suivant s'exécute :
processor.getAuthenticationSession().setAuthNote(
AuthenticationProcessor.AUTHENTICATION_SELECTOR_SCREEN_DISPLAYED, "true");
return createSelectAuthenticatorsScreen(model);
l'indicateur AuthenticationProcessor.AUTHENTICATION_SELECTOR_SCREEN_DISPLAYED est une valeur booléenne, sans aucune information indiquant quelle exécution l'a activé. Il n'est réinitialisé que dans la branche qui traite un paramètre authenticationExecution transmis. Si l'on omet ce paramètre authenticationExecution, l'indicateur reste activé pendant toute la durée de la session d'authentification.
Habituellement tryAnotherWay est utilisé lors du changement de mode d'authentification lorsque plusieurs d'entre eux sont configurés (OTP, Passkeys etc.). Lorsqu'il est activé, l'indicateur AuthenticationProcessor.AUTHENTICATION_SELECTOR_SCREEN_DISPLAYED prend la valeur "vrai" et il permet d'ignorer le flux d'exécution classique pour réorienter l'utilisateur vers une nouvelle cinématique. C'est cette fonctionnalité de changement de flux d'exécution qui pose problème lors d'un flux reset-credentials, qui n'est pas censé avoir plusieurs modes d'authentification configurés.

Utilisation légitime de Try Another Way
En effet, "Try Another Way » permet à l'utilisateur de changer de méthode d'authentification lorsqu'il en a déjà initié une. Ce lien n'apparaît que lorsque plusieurs méthodes d'authentification sont disponibles pour l'utilisateur concerné.
Par exemple, lorsqu'un utilisateur s'authentifie via login/mot de passe puis doit fournir un second facteur (OTP ou passkey), Keycloak propose ce lien pour basculer d'une méthode à l'autre : passer d'un OTP à une passkey, ou inversement. Attention, dans le cas où on a une seule méthode d'authentification, le lien n'apparaît pas mais reste invocable et donc exploitable.
La deuxième faille se trouve dans l'implémentation du service de réinitialisation de mot de passe : services/src/main/java/org/keycloak/authentication/authenticators/resetcred/ResetCredentialEmail.java
Keycloak ne vérifie pas l'action token émis dans l'email pour valider la requête de réinitialisation de mot de passe.
@Override
public void action(AuthenticationFlowContext context)
On a en effet aucune condition, ainsi le fait d'appeler action() équivaut à prouver qu'on contrôle l'adresse mail spécifiée plus tôt.
Ensemble ces failles permettent d'ignorer le flux d'exécution classique de réinitialisation de mot de passe, et de ne pas bloquer pas la requête de changement effectif du mot de passe.
Mitigation
Mise à jour de Keycloak
La solution recommandée est de mettre à jour Keycloak le plus rapidement possible vers une version qui a le patch. C'est la solution qui permet de conserver le maximum de fonctionnalités de Keycloak, toutes les autres solutions sont à mettre en place de façon temporaire en attendant de pouvoir mettre Keycloak à jour.
Désactiver la fonctionnalité de réinitialisation de mot de passe
Sans cette fonctionnalité la vulnérabilité n'est plus exploitable.
Pour être complètement protégé il faut désactiver la fonctionnalité sur tous les realms, c'est à dire tous les realms créés et le realm master.
Pour se faire on se rend dans l'interface Realm Settings > Login de chaque realm et on décoche Forgot Password.

Ce changement introduit cependant une dégradation du service d'authentification : les utilisateurs ne peuvent plus réinitialiser leur mots de passe en self-service. Il faut donc s'occuper de la réinitialisation manuellement.
Bloquer les requêtes malveillantes avec un pare-feu applicatif
Cette dernière solution tire profit du chemin d'exploitation de la vulnérabilité et permet de garder le service de réinitialisation de mot de passe actif. Elle nécessite cependant un Web Application Firewall (WAF) capable d'inspecter le corps des requêtes.
Pour fonctionner, l'exploit doit envoyer une requête POST avec dans son corps le paramètre tryAnotherWay. On va donc chercher à bloquer une requête du type :
POST /realms//login-actions/reset-credentials
?session_code=
&execution=
&client_id=
&tab_id=
HTTP/1.1 Host:
Content-Type: application/x-www-form-urlencoded
Content-Length: 17
tryAnotherWay=xxxxx
On peut alors définir une règle de pare-feu applicatif qui va venir inspecter le corps des requêtes HTTP et bloquer toutes celles qui définissent le paramètre tryAnotherWay. Ainsi, l'exploit est bloqué à la première étape.

Exemple de configuration de règle dans Microsoft Azure
Il est important de vérifier que la règle :
-
bloque le traffic et est activée
-
Aie une priorité la plus haute possible, idéalement 1
-
Inspecte le corps de la requête HTTP pour une chaîne de caractères (string) et pas dans les paramètres en URI ou les headers
-
S'active lorsque le corps contient le paramètre
tryAnotherWay
Cette solution permet de garder actif la réinitialisation par mot de passe mais elle a un inconvénient : on retire la possibilité de changer de mode d'authentification lors d'une authentification multifacteur (MFA).
En bloquant les requêtes qui initialisent ce paramètre, on supprime uniquement la possibilité de basculer entre les méthodes de MFA/OTP disponibles, sans retirer la fonctionnalité elle-même : un utilisateur peut toujours s'authentifier normalement via OTP ou passkey, simplement sans pouvoir changer de méthode en cours de route.
Détection et Audit
La communauté Keycloak a mis à disposition deux scripts qui permettent de détecter les comptes qui ont été exploités via cette vulnérabilité, en utilisant la signature produite dans les User Events.
cve-2026-18963-hunt.py
https://gist.github.com/thomasdelorge/e51e575f738a6aff865e5575f9e13912
Le premier script fonctionne en utilisant l'interface administrateur de Keycloak et nécessite de configurer un client Direct Access Grant sur le realm à analyser et d'avoir un utilisateur administrateur avec le rôle view-events. Il est aussi possible de créer ce client sur le realm master pour le réutiliser pour tous les realms, ce n'est toutefois pas recommandé pour des raisons de sécurité.

Créer le client sur le bon realm

On vient activer Direct Access Grant et Service Account Roles
Pour sécuriser la détection, on configure le client pour utiliser un secret avec Service Account Roles, Ensuite on crée un utilisateur avec view-events ou on sélectionne un compte admin pour pouvoir exécuter le script.

La commande à passer ensuite
python3 cve-2026-18963-hunt.py \
--base \
--realm \
--auth-realm \
--client \
--client-secret \
--admin \
--admin-pass \
--since 7d \
--threshold-ms 5000

cve-2026-18963-keycloak-hunt.sql
https://github.com/kyos-public/keycloak-cve-2026-18963-hunt
Le second script fonctionne en cherchant dans la base postgresql de Keycloak directement et vient aussi chercher la signature de l'attaque dans les events. Il faut donc des identifiants valides pour la base de données et permettre de lancer le script.
# defaults: realm 'master', window since 2026-06-01
psql -U keycloak -d keycloak -f cve-2026-18963-keycloak-hunt.sql
# explicit realm and window (run once per realm, quote values exactly like this)
psql -U keycloak -d keycloak
-v realm="'myrealm'" -v since="'2026-05-01'"
-f cve-2026-18963-keycloak-hunt.sql
Conclusion
La portée de cette vulnérabilité est particulièrement large car elle touche un service très souvent activé (Forgot Password) sur un panel de versions récentes (26.x.x). Il est donc important de traiter cette vulnérabilité au plus vite au risque de perdre le contrôle d'un nombre important de comptes utilisateurs, tous realms confondus.
Article rédigé par Vincent Bittard – Consultant IAM Aduneo
Aduneo
Expert cyber IAM depuis 2001
Spécialisés dans les domaines de la gestion des identités et des accès (IAM, CIAM, IGA, PAM, CIEM) et de la sécurité des infrastructures, nous aidons les organisations à sécuriser et à optimiser leurs environnements numériques on-premise, cloud et hybrides. Avec une expertise pointue dans ces secteurs critiques, nous comprenons les enjeux spécifiques de protection des données et d'accès sécurisé auxquels nos clients font face dans leur transformation digitale.
Démarrez tout de suite votre projet IAM avec nos équipes !
Nos agences
Nous contacter
Accès rapide

Sommaire
Keycloak est une solution open source de gestion des identités et des accès (IAM) qui permet de gérer l’authentification, l’autorisation et le contrôle des utilisateurs pour des applications et services grâce à des standards comme OAuth 2.0, OpenID Connect et SAML.
Le 19 août 2026 à 7:17 (heure de Paris), une vulnérabilité dans le service de réinitialisation de mot de passe de Keycloak a été communiquée publiquement sur le dépôt Github du projet, sous la référence CVE-2026-18963 (issue #51833). Cette vulnérabilité permet à un attaquant non authentifié de forcer la réinitialisation de mot de passe d’un utilisateur, sans avoir à cliquer sur le lien de vérification envoyé par mail. L’attaquant prend alors le contrôle total du compte de la victime en définissant un nouveau mot de passe. Cette vulnérabilité est pour le moment classée critique avec un score CVSS de 9.1 en raison de son impact et de sa facilité d’exploitation.
Conditions de vulnérabilité
Pour être vulnérable, une instance de Keycloak doit avoir un realm avec la fonctionnalité de réinitialisation de mot de passe activée, aussi appelée "Forgot Password". Cette fonctionnalité se trouve dans les paramètres du Realm dans Realm Settings > Login.

Exemple de configuration vulnérable
La vulnérabilité n'est présente qu'à partir de la version 26 et est en partie patchée, les versions vulnérables sont les suivantes :

Explication de la vulnérabilité
La vulnérabilité réside dans le flux reset-credentials, flux utilisé par défaut dans Keycloak lorsqu'on active la fonctionnalité de réinitialisation de mot de passe.
Deux failles chaînées, non exploitables seules, sont à l'origine de la vulnérabilité.
La première faille se trouve dans l'implémentation du flux d'authentification par défaut : services/src/main/java/org/keycloak/authentication/DefaultAuthenticationFlow.java
Où pour toute requête POST sur un endpoint du service d'authentification qui défini le paramètre tryAnotherWay, le code suivant s'exécute :
processor.getAuthenticationSession().setAuthNote(
AuthenticationProcessor.AUTHENTICATION_SELECTOR_SCREEN_DISPLAYED, "true");
return createSelectAuthenticatorsScreen(model);
l'indicateur AuthenticationProcessor.AUTHENTICATION_SELECTOR_SCREEN_DISPLAYED est une valeur booléenne, sans aucune information indiquant quelle exécution l'a activé. Il n'est réinitialisé que dans la branche qui traite un paramètre authenticationExecution transmis. Si l'on omet ce paramètre authenticationExecution, l'indicateur reste activé pendant toute la durée de la session d'authentification.
Habituellement tryAnotherWay est utilisé lors du changement de mode d'authentification lorsque plusieurs d'entre eux sont configurés (OTP, Passkeys etc.). Lorsqu'il est activé, l'indicateur AuthenticationProcessor.AUTHENTICATION_SELECTOR_SCREEN_DISPLAYED prend la valeur "vrai" et il permet d'ignorer le flux d'exécution classique pour réorienter l'utilisateur vers une nouvelle cinématique. C'est cette fonctionnalité de changement de flux d'exécution qui pose problème lors d'un flux reset-credentials, qui n'est pas censé avoir plusieurs modes d'authentification configurés.

Utilisation légitime de Try Another Way
En effet, "Try Another Way » permet à l'utilisateur de changer de méthode d'authentification lorsqu'il en a déjà initié une. Ce lien n'apparaît que lorsque plusieurs méthodes d'authentification sont disponibles pour l'utilisateur concerné.
Par exemple, lorsqu'un utilisateur s'authentifie via login/mot de passe puis doit fournir un second facteur (OTP ou passkey), Keycloak propose ce lien pour basculer d'une méthode à l'autre : passer d'un OTP à une passkey, ou inversement. Attention, dans le cas où on a une seule méthode d'authentification, le lien n'apparaît pas mais reste invocable et donc exploitable.
La deuxième faille se trouve dans l'implémentation du service de réinitialisation de mot de passe : services/src/main/java/org/keycloak/authentication/authenticators/resetcred/ResetCredentialEmail.java
Keycloak ne vérifie pas l'action token émis dans l'email pour valider la requête de réinitialisation de mot de passe.
@Override
public void action(AuthenticationFlowContext context)
On a en effet aucune condition, ainsi le fait d'appeler action() équivaut à prouver qu'on contrôle l'adresse mail spécifiée plus tôt.
Ensemble ces failles permettent d'ignorer le flux d'exécution classique de réinitialisation de mot de passe, et de ne pas bloquer pas la requête de changement effectif du mot de passe.
Mitigation
Mise à jour de Keycloak
La solution recommandée est de mettre à jour Keycloak le plus rapidement possible vers une version qui a le patch. C'est la solution qui permet de conserver le maximum de fonctionnalités de Keycloak, toutes les autres solutions sont à mettre en place de façon temporaire en attendant de pouvoir mettre Keycloak à jour.
Désactiver la fonctionnalité de réinitialisation de mot de passe
Sans cette fonctionnalité la vulnérabilité n'est plus exploitable.
Pour être complètement protégé il faut désactiver la fonctionnalité sur tous les realms, c'est à dire tous les realms créés et le realm master.
Pour se faire on se rend dans l'interface Realm Settings > Login de chaque realm et on décoche Forgot Password.

Ce changement introduit cependant une dégradation du service d'authentification : les utilisateurs ne peuvent plus réinitialiser leur mots de passe en self-service. Il faut donc s'occuper de la réinitialisation manuellement.
Bloquer les requêtes malveillantes avec un pare-feu applicatif
Cette dernière solution tire profit du chemin d'exploitation de la vulnérabilité et permet de garder le service de réinitialisation de mot de passe actif. Elle nécessite cependant un Web Application Firewall (WAF) capable d'inspecter le corps des requêtes.
Pour fonctionner, l'exploit doit envoyer une requête POST avec dans son corps le paramètre tryAnotherWay. On va donc chercher à bloquer une requête du type :
POST /realms//login-actions/reset-credentials
?session_code=
&execution=
&client_id=
&tab_id=
HTTP/1.1 Host:
Content-Type: application/x-www-form-urlencoded
Content-Length: 17
tryAnotherWay=xxxxx
On peut alors définir une règle de pare-feu applicatif qui va venir inspecter le corps des requêtes HTTP et bloquer toutes celles qui définissent le paramètre tryAnotherWay. Ainsi, l'exploit est bloqué à la première étape.

Exemple de configuration de règle dans Microsoft Azure
Il est important de vérifier que la règle :
-
bloque le traffic et est activée
-
Aie une priorité la plus haute possible, idéalement 1
-
Inspecte le corps de la requête HTTP pour une chaîne de caractères (string) et pas dans les paramètres en URI ou les headers
-
S'active lorsque le corps contient le paramètre
tryAnotherWay
Cette solution permet de garder actif la réinitialisation par mot de passe mais elle a un inconvénient : on retire la possibilité de changer de mode d'authentification lors d'une authentification multifacteur (MFA).
En bloquant les requêtes qui initialisent ce paramètre, on supprime uniquement la possibilité de basculer entre les méthodes de MFA/OTP disponibles, sans retirer la fonctionnalité elle-même : un utilisateur peut toujours s'authentifier normalement via OTP ou passkey, simplement sans pouvoir changer de méthode en cours de route.
Détection et Audit
La communauté Keycloak a mis à disposition deux scripts qui permettent de détecter les comptes qui ont été exploités via cette vulnérabilité, en utilisant la signature produite dans les User Events.
cve-2026-18963-hunt.py
https://gist.github.com/thomasdelorge/e51e575f738a6aff865e5575f9e13912
Le premier script fonctionne en utilisant l'interface administrateur de Keycloak et nécessite de configurer un client Direct Access Grant sur le realm à analyser et d'avoir un utilisateur administrateur avec le rôle view-events. Il est aussi possible de créer ce client sur le realm master pour le réutiliser pour tous les realms, ce n'est toutefois pas recommandé pour des raisons de sécurité.

Créer le client sur le bon realm

On vient activer Direct Access Grant et Service Account Roles
Pour sécuriser la détection, on configure le client pour utiliser un secret avec Service Account Roles, Ensuite on crée un utilisateur avec view-events ou on sélectionne un compte admin pour pouvoir exécuter le script.

La commande à passer ensuite
python3 cve-2026-18963-hunt.py \
--base \
--realm \
--auth-realm \
--client \
--client-secret \
--admin \
--admin-pass \
--since 7d \
--threshold-ms 5000

cve-2026-18963-keycloak-hunt.sql
https://github.com/kyos-public/keycloak-cve-2026-18963-hunt
Le second script fonctionne en cherchant dans la base postgresql de Keycloak directement et vient aussi chercher la signature de l'attaque dans les events. Il faut donc des identifiants valides pour la base de données et permettre de lancer le script.
# defaults: realm 'master', window since 2026-06-01
psql -U keycloak -d keycloak -f cve-2026-18963-keycloak-hunt.sql
# explicit realm and window (run once per realm, quote values exactly like this)
psql -U keycloak -d keycloak
-v realm="'myrealm'" -v since="'2026-05-01'"
-f cve-2026-18963-keycloak-hunt.sql
Conclusion
La portée de cette vulnérabilité est particulièrement large car elle touche un service très souvent activé (Forgot Password) sur un panel de versions récentes (26.x.x). Il est donc important de traiter cette vulnérabilité au plus vite au risque de perdre le contrôle d'un nombre important de comptes utilisateurs, tous realms confondus.
Article rédigé par Vincent Bittard – Consultant IAM Aduneo


