صف الخطأ
عند استخدام Discourse كمزود DiscourseConnect (مزود SSO)، يتم الكشف عن عنوان البريد الإلكتروني للمستخدم في عنوان URL لإعادة التوجيه 302 إلى الطرف المعتمد. يحدث هذا لأن الدالة populate_user_data في lib/second_factor/actions/discourse_connect_provider.rb تقوم دائمًا بتعيين البريد الإلكتروني:
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
- التحقق من عنوان URL لإعادة التوجيه 302 - يظهر البريد الإلكتروني في معلمات عنوان 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: (الأحدث)
- مستضاف ذاتيًا
اقتراحات إصلاح محتملة
- إضافة إعداد موقع مثل
discourse_connect_provider_includes_email(الافتراضي:trueللتوافق مع الإصدارات السابقة) للتحكم فيما إذا كان البريد الإلكتروني مدرجًا في الاستجابة - أو تنفيذ رد اتصال قائم على POST بدلاً من إعادة توجيه GET 302 لتجنب تسجيل عنوان URL