Описание ошибки
При использовании Discourse в качестве поставщика DiscourseConnect (поставщика SSO) адрес электронной почты пользователя раскрывается в URL-адресе перенаправления 302 для доверяющей стороны. Это происходит из-за того, что метод populate_user_data в файле lib/second_factor/actions/discourse_connect_provider.rb всегда устанавливает значение поля email:
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
Затем этот email кодируется в 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.
- Проверьте URL-адрес перенаправления 302 — адрес электронной почты виден в параметрах URL.
URL-адрес перенаправления выглядит следующим образом:
https://relying-party.com/sso?sso=bm9uY2U9xxx&sig=xxx
Декодирование параметра sso раскрывает:
nonce=xxx&return_sso_url=xxx&email=user@example.com&external_id=123
Окружение
- Версия Discourse: (последняя)
- Размещение на собственном сервере
Предложения по возможному исправлению
- Добавить настройку сайта, например
discourse_connect_provider_includes_email(по умолчанию: true для обратной совместимости), чтобы контролировать, включается ли адрес электронной почты в ответ. - Или реализовать обратный вызов на основе POST вместо перенаправления 302 через GET, чтобы избежать записи URL в логи.