Descrivi il bug
Quando si utilizza Discourse come DiscourseConnect Provider (SSO Provider), l’indirizzo email dell’utente viene esposto nell’URL di reindirizzamento 302 verso il relying party. Ciò accade perché il metodo populate_user_data in lib/second_factor/actions/discourse_connect_provider.rb imposta sempre l’email:
def populate_user_data(sso)
sso.name = current_user.name
sso.username = current_user.username
sso.email = current_user.email # <-- Sempre incluso
sso.external_id = current_user.id.to_s
# ...
end
Questa email viene quindi codificata in Base64 e inclusa nell’URL di reindirizzamento:
https://target-site.com/callback?sso=<base64_payload>&sig=<hmac_signature>
La decodifica del payload base64 rivela l’indirizzo email in testo semplice.
Impatto
- Cronologia del browser: l’email viene registrata nella cronologia del browser
- Log di Nginx: l’URL completo viene registrato nei log di accesso di nginx
- Log del sito di destinazione: il relying party riceve l’email senza esplicito consenso dell’utente
- Aspettativa dell’utente: gli utenti di solito autorizzano per dimostrare “Sono un utente legittimo”, non si aspettano che la loro email venga condivisa
Comportamento previsto
Gli utenti dovrebbero essere in grado di controllare se la loro email viene condivisa con il relying party. Dovrebbe esserci un’opzione di configurazione simile a discourse_connect_overrides_groups, discourse_connect_overrides_avatar, ecc.
Attualmente non esiste un’impostazione del sito per disabilitare questo comportamento. Scrivere un plugin per sovrascrivere questo comportamento è possibile ma non ideale.
Passaggi per la riproduzione
- Abilitare
enable_discourse_connect_provider - Configurare
discourse_connect_provider_secrets(es. *.example.com|secret123) - Far autenticare un utente tramite DiscourseConnect Provider
- Controllare l’URL di reindirizzamento 302 - l’email è visibile nei parametri dell’URL
L’URL di reindirizzamento appare come:
https://relying-party.com/sso?sso=nonce=xxx&sig=xxx
La decodifica del parametro sso rivela:
nonce=xxx&return_sso_url=xxx&email=user@example.com&external_id=123
Ambiente
- Versione di Discourse: (latest)
- Self-hosted
Possibili suggerimenti per la correzione
- Aggiungere un’impostazione del sito come
discourse_connect_provider_includes_email(default: true per retrocompatibilità) per controllare se l’email è inclusa nella risposta - Oppure implementare il callback basato su POST invece del reindirizzamento GET 302 per evitare la registrazione dell’URL