Décrire le bogue
Lors de l’utilisation de Discourse comme Fournisseur DiscourseConnect (Fournisseur SSO), l’adresse e-mail de l’utilisateur est exposée dans l’URL de redirection 302 vers le relying party (partie prenante). Cela se produit car la méthode populate_user_data dans lib/second_factor/actions/discourse_connect_provider.rb définit toujours l’e-mail :
def populate_user_data(sso)
sso.name = current_user.name
sso.username = current_user.username
sso.email = current_user.email # <-- Toujours inclus
sso.external_id = current_user.id.to_s
# ...
end
Cet e-mail est ensuite encodé en Base64 et inclus dans l’URL de redirection :
https://site-cible.com/callback?sso=<payload_base64>&sig=<signature_hmac>
Le décodage de la charge utile base64 révèle l’adresse e-mail en texte clair.
Impact
- Historique du navigateur : L’e-mail est enregistré dans l’historique du navigateur
- Journaux Nginx : L’URL complète est enregistrée dans les journaux d’accès nginx
- Journaux du site cible : Le relying party reçoit l’e-mail sans consentement explicite de l’utilisateur
- Attente de l’utilisateur : Les utilisateurs autorisent généralement pour prouver « Je suis un utilisateur légitime » - ils ne s’attendent pas à ce que leur e-mail soit partagé
Comportement attendu
Les utilisateurs devraient pouvoir contrôler si leur e-mail est partagé avec le relying party. Il devrait y avoir une option de configuration similaire à discourse_connect_overrides_groups, discourse_connect_overrides_avatar, etc.
Actuellement, il n’y a aucun paramètre de site pour désactiver ce comportement. Écrire un plugin pour remplacer ce comportement est possible mais pas idéal.
Étapes de reproduction
- Activer
enable_discourse_connect_provider - Configurer
discourse_connect_provider_secrets(par exemple,*.example.com|secret123) - Faire authentifier un utilisateur via le Fournisseur DiscourseConnect
- Vérifier l’URL de redirection 302 - l’e-mail est visible dans les paramètres de l’URL
L’URL de redirection ressemble à :
https://relying-party.com/sso?sso=nonce=xxx&sig=xxx
Le décodage du paramètre sso révèle :
nonce=xxx&return_sso_url=xxx&email=user@example.com&external_id=123
Environnement
- Version de Discourse : (la plus récente)
- Auto-hébergé
Suggestions de correction possibles
- Ajouter un paramètre de site comme
discourse_connect_provider_includes_email(par défaut :truepour la rétrocompatibilité) pour contrôler si l’e-mail est inclus dans la réponse - Ou implémenter un rappel basé sur POST au lieu d’une redirection GET 302 pour éviter l’enregistrement de l’URL