보안/프라이버시 문제: DiscourseConnect 제공자 리다이렉트 URL에 이메일 노출

버그 설명

DiscourseConnect Provider (SSO Provider)로 Discourse를 사용할 때, 사용자가 의존하는 당사(Relying Party)로 보내는 302 리다이렉트 URL에 이메일 주소가 노출됩니다. 이는 lib/second_factor/actions/discourse_connect_provider.rbpopulate_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 페이로드를 디코딩하면 이메일 주소가 평문으로 확인됩니다.

영향

  1. 브라우저 기록: 이메일이 브라우저 기록에 남습니다.
  2. Nginx 로그: 전체 URL이 nginx 액세스 로그에 기록됩니다.
  3. 대상 사이트 로그: 의존하는 당사가 사용자의 명시적 동의 없이 이메일을 수신합니다.
  4. 사용자 기대: 사용자는 일반적으로 "나는 합법적인 사용자입니다"라는 것을 증명하기 위해 인증을 허용할 뿐, 이메일이 공유될 것이라고 기대하지 않습니다.

기대되는 동작

사용자는 의존하는 당사에게 이메일을 공유할지 여부를 제어할 수 있어야 합니다. discourse_connect_overrides_groups, discourse_connect_overrides_avatar 등과 유사한 구성 옵션이 있어야 합니다.

현재 이 동작을 비활성화할 사이트 설정이 없습니다. 이 동작을 오버라이드하는 플러그인을 작성하는 것은 가능하지만 이상적이지 않습니다.

재현 단계

  1. enable_discourse_connect_provider를 활성화합니다.
  2. discourse_connect_provider_secrets를 구성합니다 (예: *.example.com|secret123).
  3. 사용자가 DiscourseConnect Provider를 통해 인증하도록 합니다.
  4. 302 리다이렉트 URL을 확인합니다 - 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 버전: (최신)
  • 셀프 호스팅

가능한 수정 제안

  1. 응답에 이메일을 포함할지 여부를 제어하기 위해 discourse_connect_provider_includes_email (기본값: 하위 호환성을 위해 true)와 같은 사이트 설정을 추가합니다.
  2. 또는 URL 로깅을 피하기 위해 GET 302 리다이렉트 대신 POST 기반 콜백을 구현합니다.
1개의 좋아요

그것도 공유 시크릿으로 암호화되지 않나요?

1개의 좋아요

Falco님, 안녕하세요.

HMAC 서명은 페이로드가 변조되지 않았다는 것만 보장할 뿐, 데이터를 암호화하지는 않습니다. Base64는 인코딩이지 암호화가 아니므로, 누구나 디코딩하여 내용을 읽을 수 있습니다.

핵심 문제는 다음과 같습니다: "SSO 로그인을 위해 Discourse를 사용하는 제3자 사이트"에 불필요한 사용자 정보(예: 이메일)를 노출하고 싶지 않습니다. 사용자는 "저는 legitimate 사용자입니다"라는 사실만 증명하기 위해 권한을 부여할 뿐, 이메일이 공유될 것이라고 기대하지는 않습니다.

이메일을 반환할지 여부를 제어하는 사이트 설정을 추가하는 것이 허용될 수 있을까요?

저는 궁금한 점이 있습니다. 이 커스텀 SSO 프로토콜을 구현한 하위 제3자 사이트는 어디인가요?

기존 사이트가 깨지지 않도록 기본값으로 설정되지 않는 한, #pr-welcome이라고 하겠습니다.

피드백 감사합니다!

사용 사례에 대한 배경 정보를 드리겠습니다. 저희 포럼은 "캠퍼스 포럼"이며, 한 학생이 다른 학생들이 사용할 수 있는 무료 웹사이트를 구축했습니다. 이들은 저희 Discourse 기반의 캠퍼스 포럼을 사용하여 사용자가 실제로 저희 학교의 학생인지 인증하려는 것입니다. 즉, "저는 이 학교의 정당한 학생입니다"라는 사실을 증명하는 것이죠.

이 시나리오에서 외부 웹사이트는 "이 사용자는 저희 캠퍼스 포럼의 유효한 사용자입니다"라는 사실만 알면 충분하며, 불필요하게 공유해서는 안 되는 민감한 정보인 사용자의 이메일 주소를 반드시 알아야 할 필요는 없습니다.

기존 설치 환경과의 하위 호환성을 유지하는 기본값을 포함하여, 이 동작을 제어할 수 있는 사이트 설정을 추가하는 PR을 작업하겠습니다.

4개의 좋아요

PR 링크입니다