バグの説明
Discourse を DiscourseConnect プロバイダー (SSO プロバイダー)として使用すると、ユーザーのメールアドレスがリライングパーティへの 302 リダイレクト URL で公開されます。これは、lib/second_factor/actions/discourse_connect_provider.rb の populate_user_data メソッドが常にメールを設定するためです。
def populate_user_data(sso)
sso.name = current_user.name
sso.username = current_user.username
sso.email = current_user.email # <-- 常に含まれる
sso.external_id = current_user.id.to_s
# ...
end
このメールアドレスは Base64 でエンコードされ、リダイレクト URL に含まれます。
https://target-site.com/callback?sso=<base64_payload>&sig=<hmac_signature>
Base64 ペイロードをデコードすると、メールアドレスがプレーンテキストで表示されます。
影響
- ブラウザの履歴: メールアドレスがブラウザの履歴に記録される
- Nginx ログ: 完全な URL が nginx アクセスログに記録される
- リライングパーティのログ: リライングパーティが明示的なユーザーの同意なしにメールアドレスを受け取る
- ユーザーの期待: ユーザーは通常、「自分が正当なユーザーであることを証明する」ことに同意するのであり、メールアドレスが共有されることを期待していません。
期待される動作
ユーザーは、メールアドレスをリライングパーティと共有するかどうかを制御できる必要があります。discourse_connect_overrides_groups や discourse_connect_overrides_avatar などと同様の設定オプションが必要です。
現在、この動作を無効にするためのサイト設定はありません。動作を上書きするためにプラグインを作成することは可能ですが、理想的ではありません。
再現手順
enable_discourse_connect_providerを有効にするdiscourse_connect_provider_secretsを設定する (例: *.example.com|secret123)- ユーザーが DiscourseConnect Provider 経由で認証する
- 302 リダイレクト URL を確認する - メールアドレスが URL パラメータに表示されている
リダイレクト URL は次のようになります。
https://relying-party.com/sso?sso=nonce=xxx&sig=xxx
sso パラメータをデコードすると、次のように表示されます。
nonce=xxx&return_sso_url=xxx&email=user@example.com&external_id=123
環境
- Discourse バージョン: (最新)
- セルフホスト型
考えられる修正案
- レスポンスにメールを含めるかどうかを制御するためのサイト設定 (後方互換性のためにデフォルトは true) として
discourse_connect_provider_includes_emailを追加する - または、URL のロギングを避けるために GET 302 リダイレクトの代わりに POST ベースのコールバックを実装する