
الإفصاح المسؤول عن ثغرة أمنية غير مصححة في FluentCRM من WPManageNinja
تحديث 2023-06-12: لم تعد بحاجة إلى المقتطف. قامت WPManageNinja بتصحيح الثغرة بعد ساعتين من الإفصاح العام (93 يومًا بعد الإبلاغ).
تحديث 2024-01-27: تم الآن معالجة المشكلة ذات الصلة بقيم التجزئة الدائمة بشكل كامل.
tl;dr يمكن للمهاجمين عرض وتعديل تفاصيل جهات الاتصال في FluentCRM. لم تقم WPManageNinja بتصحيح الثغرة خلال فترة الإفصاح المسؤول البالغة 90 يومًا. أقدم مقتطف تخفيف لمنع استغلال الثغرة أثناء انتظار التصحيح الرسمي.
اليوم، أنشر معلومات حول ثغرة وجدتها في الإضافة الشهيرة لووردبريس FluentCRM من WPManageNinja. الثغرة، CVE-2023-1430، ناتجة عن استخدام غير كافٍ من FluentCRM لتجزئة عنوان البريد الإلكتروني كعنصر تحكم في التفويض. لقد أفصحت عن الثغرة بمسؤولية وفقًا لسياسة الإفصاح عن الثغرات الخاصة بـ Google Zero. لم تقدم WPManageNinja تصحيحًا خلال فترة 90 يومًا، ولا طلبت تمديدًا للوقت.
في هذا التقرير، يشير contact إلى كائن جهة اتصال في FluentCRM، بينما يشير user إلى كائن مستخدم ووردبريس. يمكن ربط جهة اتصال بمستخدم، لكنه ليس شرطًا. تم حجب تفاصيل استغلال الثغرة حتى يتوفر تصحيح رسمي. يمكن لمحترفي الأمن التواصل معي للحصول على التقرير الكامل ([email protected]).
على المواقع التي تشغل FluentCRM، يمكن للمهاجم عرض وتعديل اسم جهة الاتصال وعنوان بريدها الإلكتروني وإعداد القائمة بمجرد معرفة عنوان بريد جهة الاتصال. نظرًا لأن اسم جهة الاتصال غالبًا ما يتم تضمينه في النشرات الإخبارية عبر علامات الدمج، يمكن للمهاجم استبدال اسم جهة الاتصال بلغة بذيئة، مما يتسبب في إرسال مالك الموقع لنشرات إخبارية فظة. إذا قام مدير الموقع بتمكين الرمز القصير لإدارة التفضيلات في FluentCRM وأضافه إلى صفحة ويب عامة، يمكن للمهاجم عرض وتعديل جميع المعلومات الشخصية المكشوفة، أي اللقب ورقم الهاتف وتاريخ الميلاد والعنوان (اعتمادًا على تكوين FluentCRM).
تم تثبيت FluentCRM على أكثر من 30,000 موقع. يمكن لمديري المواقع التي تستخدم FluentCRM منع استغلال الثغرة عن طريق إضافة مقتطف التخفيف الخاص بي إلى ملف functions.php في القالب الفرعي.
لا يقوم المقتطف بتصحيح الثغرة. يقوم باستبدال المحتوى الضعيف في صفحة إلغاء الاشتراك (unsubscribe.php) وصفحة إدارة التفضيلات (manage_subscription.php) في FluentCRM برسالة خطأ تطلب من جهة الاتصال التواصل عبر البريد الإلكتروني بدلاً من ذلك. عنوان البريد الإلكتروني في رسالة الخطأ هو عنوان بريد المسؤول (يمكن تغييره من المقتطف). يضمن مقتطف التخفيف أيضًا أن الزوار غير المسجلين لا يمكنهم عرض الرمز القصير الضعيف لإدارة التفضيلات (fluentcrm_pref). سيرى الزائر غير المسجل بدلاً من ذلك رسالة خطأ تطلب منه تسجيل الدخول. جميع النصوص قابلة للترجمة باستخدام ملف POT المقدم.
أوصي مالكي المواقع بتنفيذ إما التخفيف الذي أقدمه أو التخفيف المناسب الخاص بهم. يجب على مالكي المواقع أيضًا التحقق من سلامة بيانات جهات الاتصال في FluentCRM، وإذا أمكن، فحص سجلاتهم بحثًا عن تسريبات محتملة للبيانات. يعد فحص السجلات مهمًا بشكل خاص للمواقع التالية:
يجب على مراقب البيانات المعين للموقع التعامل مع أي تسريبات محتملة للبيانات الشخصية وفقًا للقوانين واللوائح في الولايات القضائية المتأثرة.
إذا تم تكوين FluentCRM لمزامنة إعدادات جهة الاتصال مع المستخدم المقابل لها، يمكن للمهاجم تغيير اسم المستخدم. لحسن الحظ، لا يقوم FluentCRM بمزامنة عناوين البريد الإلكتروني من جهات الاتصال إلى المستخدمين. إذا كان FluentCRM يفعل ذلك، لكانت هذه الثغرة تمكن من السيطرة الكاملة على الموقع. كان بإمكان المهاجم الحصول على وصول مميز عن طريق تغيير عنوان البريد الإلكتروني لمسؤول الموقع ثم إعادة تعيين كلمة مرور المسؤول.
ومع ذلك، يمكن للحلول الأخرى مزامنة جميع البيانات الوصفية من جهات الاتصال إلى المستخدمين، مثل WP Fusion وواجهة برمجة تطبيقات FluentCRM. من المحتمل أن يكون WP Fusion هو الإضافة الأكثر شيوعًا من طرف ثالث لمزامنة بيانات جهات الاتصال الوصفية بين CRM (مثل FluentCRM) ووردبريس. لحسن الحظ، الإصدار الحالي من WP Fusion غير مرتبط بتغييرات البيانات الوصفية التي تم بدؤها من النماذج الضعيفة. لقد أبلغت مطوري WP Fusion، ولن يعالجوا هذا القيد حتى تقوم WPManageNinja بتصحيح الثغرة.
يمكن أيضًا استخدام واجهة برمجة تطبيقات FluentCRM لتحديث بيانات جهات الاتصال والمستخدمين. يجب على مالكي المواقع الذين يستخدمون واجهة برمجة تطبيقات FluentCRM لتحديث عناوين البريد الإلكتروني للمستخدمين تعطيل هذا التحديث عندما يتم البدء به من صفحة FluentCRM أو الرمز القصير لإدارة التفضيلات (أو إضافة مقتطف التخفيف الخاص بي لضمان عدم إمكانية تحديث أي إعدادات من النماذج الضعيفة).
يتيح FluentCRM لجهات الاتصال إلغاء الاشتراك وإدارة التفضيلات من صفحات ويب عامة. يتم تضمين روابط لهذه الصفحات في كل نشرة إخبارية. يتم تفويض التغييرات التي تتم على هذه الصفحات بواسطة تجزئات MD5 لعناوين البريد الإلكتروني لجهات الاتصال، ويتم تمريرها كمعلمات URL. تجزئة MD5 لعنوان البريد الإلكتروني ليست سرًا ويمكن لأي شخص حسابها. يمكن للمهاجم استغلال الاستخدام غير الصحيح للتجزئات لإلغاء اشتراك جهات اتصال محددة أو إلغاء اشتراك جهات اتصال بعناوين بريد إلكتروني معروفة بشكل جماعي.
بينما تعتمد صفحة إلغاء الاشتراك فقط على تجزئة MD5 للتفويض، تتطلب صفحة إدارة التفضيلات معلمة URL إضافية تسمى ce_id. في هذه الحالة، يشير ce_id إلى معرف جهة الاتصال في جدول fc_subscribers. هذا المعرف هو عدد صحيح متزايد. لذلك يمكن بسهولة العثور على قيمة ce_id عن طريق اختبار جميع القيم الممكنة (مساحة البحث هي عدد جهات الاتصال المسجلة في الموقع). ربما يكون لدى المستخدمين المسؤولين قيم منخفضة.
من صفحة إدارة التفضيلات، يمكن للمهاجم أيضًا استخراج قيمة secure_hash لجهة الاتصال. عن طريق تحديث عنوان البريد الإلكتروني لجهة الاتصال، يتم تخزين قيمة "secure_hash" في ملف تعريف ارتباط يسمى fc_hash_secure. مع وجود ملف تعريف الارتباط هذا، يمكن للمهاجم عرض جميع معلومات جهة الاتصال المتاحة بواسطة الرمز القصير لنموذج التفضيلات في FluentCRM.
"secure_hash" المذكورة سابقًا هي قيمة يعتمد عليها FluentCRM (في بعض الحالات) بدلاً من أو كبديل لتجزئة عنوان البريد الإلكتروني MD5. منذ إصدار FluentCRM 2.8.0، تعتمد صفحة إلغاء الاشتراك حصريًا على قيمة secure_hash للتفويض. تقبل صفحة إدارة التفضيلات كلًا من قيمة secure_hash الجديدة وتجزئة MD5 القديمة للتفويض.
بينما لا يمكن اشتقاق قيمة secure_hash من عنوان البريد الإلكتروني، فإن استخدام FluentCRM لا يتبع ممارسات الأمان الجيدة. يتم إنشاء قيمة secure_hash مرة واحدة لكل جهة اتصال. لا يتم تحديثها أبدًا، ولا تنتهي صلاحيتها أبدًا. هذا مشكلة لأن قيمة secure_hash يتم تضمينها في كل نشرة إخبارية. إذا حصل مهاجم على حق الوصول إلى صندوق الوارد لجهة الاتصال، يمكن للمهاجم تغيير إعدادات جهة الاتصال إلى أجل غير مسمى. إذا كانت جهة الاتصال المتأثرة مرتبطة بمستخدم بصلاحيات إدارية، وتمت مزامنة تغييرات عنوان البريد الإلكتروني من FluentCRM إلى ووردبريس، فإن كل نشرة إخبارية يتم إرسالها إلى جهة الاتصال هذه ستحتوي على رمز لا ينتهي أبدًا للسيطرة على الموقع.
أبلغت عن هذه المشكلة ذات الصلة إلى WPManageNinja في 2023-03-15. بعد شهرين (2023-05-15)، ردت WPManageNinja بأن مستشاريهم الأمنيين لم يعتبروا قيمة secure_hash الثابتة مشكلة. قال مستشارو الأمن في WPManageNinja أنه "من المقبول استخدام هذا النوع من الرموز المولدة لمرة واحدة لتحديد جهة الاتصال" وأنها "مشابهة لرموز API لخدمات SaaS التي لا يتم تسليمها إلى أي جهات اتصال أخرى ولكن يتم إرسالها فقط إلى جهة الاتصال الفعلية التي تملك عنوان البريد الإلكتروني".
كانت WPManageNinja منفتحة وأخبروني أن أخبرهم إذا كنت لا أزال أعتقد أنها مشكلة أمنية، وقد فعلت ذلك. شرحت لماذا لا يمكن مقارنة قيم secure_hash برموز API. (يمكن ضمان إرسال رموز API فقط عبر اتصالات TLS، ويمكن تقييد الوصول إلى رموز API. هذا ليس هو الحال مع القيم النصية الصريحة في رسائل البريد الإلكتروني. الأهم من ذلك، يمكن إلغاء رموز API بينما لا توجد طريقة لجهة الاتصال لإلغاء قيمة secure_hash.)
في وقت لاحق من نفس اليوم، شكرتني WPManageNinja وقالت إنهم يفكرون في الجمع بين معرف سجل البريد الإلكتروني والتجزئة. سيؤدي ذلك إلى حل المشكلة إذا تم تنفيذه بالتزامن مع الإلغاء التلقائي إما لقيم secure_hash القديمة (انتهاء صلاحية زمني) أو السابقة (انتهاء صلاحية قائم على العداد). لم يتم تنفيذ هذه الميزة بعد، لكنني لا أعتبر استخدام قيم التجزئة الثابتة جزءًا من CVE هذه.
في الربع الأول من 2023، بدأنا الهجرة من أداة النشرة الإخبارية السابقة (Sendy) إلى FluentCRM. وجدت الثغرة أثناء دمج FluentCRM مع أكاديمية Nikka Systems (مشروع Opal). نظرًا لأننا استبدلنا نظام إدارة الاشتراكات في FluentCRM بإضافتنا المخصصة، فإن النماذج الضعيفة في FluentCRM لم تؤثر أبدًا على موقعنا أو بيانات عملائنا.
FluentCRM هي إضافة رائعة، لكن تعامل WPManageNinja مع الإفصاح عن الثغرة يترك مجالًا كبيرًا للتحسين. القائمة التالية هي اقتراحي لكيفية تحسين WPManageNinja للوضع.
ومع ذلك، لا يزال لدي ثقة في WPManageNinja. هناك أخطاء في جميع البرامج، وتقرير ثغرة واحد سيئ الإدارة ليس سببًا للتوقف عن استخدام إضافاتهم.
تحديث 2023-06-12: حقيقة أنهم ما زالوا يحاولون إخفاء الثغرة في سجل التغييرات يجعلني قلقًا حقًا. (لقد أضافوا الآن CVE.)