الحالة 04 — SKRED Messenger

مفتاح واحد
لجميع الأجهزة.

SKRED تطبيق مراسلة مفتوح المصدر يدعم التشفير من طرف إلى طرف. وأثناء مراجعة الشيفرة الخاصة بإدارة المفاتيح، وجدت مفتاحًا احتياطيًا يتطابق على جميع الأجهزة. أبلغت عنه عبر BSI CERT-Bund، فجاء ردّ الشركة كما نرجو في مثل هذه الحالات: انفتاح، وتوضيح تقني مفصّل، وإصلاح سريع.

بقلم عباس حسيني· بتنسيق من BSI CERT-Bund وCERT/CC· الجهة المطوّرة: SKRED SAS / Twinlife

ليس كل خلل كارثة، ولا تحتاج كل حالة جديرة بالعرض إلى اكتشاف صاخب. هذه حكاية خطأ صغير ومحدّد في تطبيق مراسلة مفتوح المصدر؛ وهي، قبل ذلك، حكاية استجابة توضّح كيف ينبغي أن يجري الإفصاح المنسّق.

مفتاح واحد يصل إلى هواتف متطابقة عدة المفتاح نفسه على كل جهاز
الشكل 1 — مفتاح واحد للجميع

يخزّن SKRED الإعدادات الحساسة مشفّرةً على الجهاز. في الوضع المعتاد، ينشئ مفتاحًا خاصًا بكل جهاز داخل مخزن المفاتيح الآمن في الهاتف (Android Keystore). وإذا تعذّر ذلك ــ وهي مشكلة معروفة في بعض الأجهزة القديمة ــ كان يلجأ إلى مفتاح احتياطي ثابت. هذا المفتاح كان واحدًا في كل عمليات التثبيت.

لماذا وُجد هذا المسار؟ كانت الغاية حماية البيانات حتى عند تعطل Keystore في الجهاز. لكن المفتاح الاحتياطي لم يكن خاصًا بكل جهاز؛ بل كان يُشتق على نحو حتمي من قيمتين ثابتتين في الشيفرة. لذا تطابق في كل مكان، وكان بالإمكان إعادة بنائه من الشيفرة المنشورة.

ماذا يعني ذلك، دون مبالغة؟ كان هذا مسارًا احتياطيًا لا طريقة التشفير المعتادة. وقد تعلّق بإعدادات محفوظة محليًا، لا بمحتوى رسائل جميع المستخدمين. استغلاله يتطلب الوصول إلى الجهاز نفسه، وليس هجومًا عن بُعد. تنحصر خطورة الخلل في حالة محلية مرتبطة بالجهاز: خلل حقيقي، لكن حدوده واضحة.

المفتاح الاحتياطي موضوع جانبًا ولا يُستخدم إلا لقراءة بيانات قديمة الآن: توقّف آمن عند الخطأ المفتاح الاحتياطي لقراءة البيانات القديمة فقط
الشكل 2 — كيف أصلحت الشركة الخلل

لم يعد المفتاح الاحتياطي يُستخدم للتشفير في الوضع الحالي. فإذا فشل إنشاء المفتاح في Keystore، يتوقف التطبيق بأمان بدل المتابعة بمفتاح معروف. ولا يبقى المفتاح القديم إلا لفك تشفير البيانات الموجودة مسبقًا أثناء نقلها.

استجابة الشركة

ردّ شخصي، وإصلاح فعلي.

بعد أن أحال BSI البلاغ، ردّ المسؤول التقني في الشركة بنفسه. لم يكن ردًا جاهزًا؛ بل تناول النقاط واحدةً واحدة، مع شرح تقني مفصّل. شارك وثائق إضافية عن بنية التطبيق، وأحال إلى الشيفرة المفتوحة، وبدأ الإصلاحات فورًا. وإلى جانب معالجة المفتاح الاحتياطي، أُضيف تثبيت بصمات الشهادات أيضًا. ويمكن تتبّع هذه التغييرات كلها في مستودع الشيفرة المفتوح.

ما تعلّمته من الحالة

هكذا ينبغي أن تسير الأمور.

لا تُقاس قيمة الإفصاح المنسّق بحجم الثغرة وحده، بل بما يحدث بعد الإبلاغ عنها. قدّم SKRED مثالًا جيدًا: شيفرة مفتوحة، وشخص يردّ، وتعاون بدل التصلّب، وإصلاحات سريعة يمكن التحقق منها. وانفتاح شيفرة التطبيقات جزء من هذا النهج أيضًا.

التقرير التقني

SKRED Messenger — التحليل والمعالجة

الملخص

SKRED Messenger (من SKRED SAS / Twinlife، فرنسا) مفتوح المصدر على Android وiOS بموجب AGPL. راجعت التطبيق المنشور إلى جانب شيفرته المفتوحة. يغطي هذا التقرير مسألتين عولجتا: مفتاح AES احتياطي ثابت في طبقة إدارة المفاتيح، وغياب إعدادات تثبيت بصمات الشهادات. أُبلغ عن المسألتين ضمن إفصاح منسّق تولاه BSI CERT-Bund (وCERT/CC، المرجع VU#629507)، وأصلحتهما الشركة. ويمكن التحقق من حالة الإصلاح في الشيفرة المفتوحة.

النتيجة 1 · إدارة المفاتيح

مفتاح AES احتياطي يُشتق حتميًا ويتطابق على جميع الأجهزة

ماذا كان يحدث؟

تحمي طبقة إدارة المفاتيح (KeyChain) الإعدادات «المؤمّنة» المحفوظة محليًا بمفتاح من Android Keystore. وإذا فشل إنشاء هذا المفتاح ــ وهي مشكلة معروفة في بعض الأجهزة أو نسخ النظام القديمة ــ كان التطبيق ينتقل إلى مفتاح ثابت مضمّن في الشيفرة. وكان يُشتق حتميًا من مصفوفتَي بايت ثابتتين باستخدام XOR، ما جعله متطابقًا في كل تثبيت:

// simplified from the open-source KeyChain implementation
static Key getDefaultSecretKey() {
    int n = Math.min(UUID1.length, UUID2.length);
    byte[] key = new byte[n];
    for (int i = 0; i < n; i++)
        key[i] = (byte) (UUID1[i] ^ UUID2[n - 1 - i]);
    return new SecretKeySpec(key, "AES");   // 128-bit, same on every device
}

الأثر الأمني

على جهاز تعطل فيه Keystore، كانت الإعدادات «المؤمّنة» محليًا محميةً بمفتاح معروف للعموم. وكان بوسع من لديه وصول محلي إلى جهاز كهذا فك تشفير تلك البيانات. هذا مسار احتياطي لا الوضع المعتاد، والوصول المطلوب محلي ومرتبط بالجهاز. لا هجوم عن بُعد هنا، ولا كشف لمحتوى رسائل جميع المستخدمين.

معالجة الشركة

لم يعد المفتاح الاحتياطي يُستخدم للتشفير. فإذا فشل إنشاء المفتاح في Keystore، يتوقف التطبيق بحالة خطأ بدل تشفير البيانات بالمفتاح المعروف. ولا يُستخدم المفتاح الآن إلا لفك تشفير البيانات الموجودة مسبقًا أثناء نقلها. وأُسقط دعم Android 5.0/5.1، اللذين كانا المصدر الرئيسي لمشكلة Keystore. وقد تحققت من التغييرات في الشيفرة المفتوحة.

النتيجة 2 · أمن الشبكة

غياب تثبيت بصمات الشهادات

ماذا كان يحدث؟

كان التطبيق يُنشر من دون إعدادات لأمن الشبكة. وكان من الممكن أن تسمح شهادة مثبّتة على الجهاز ــ مثلًا في بيئة مُدارة ــ باعتراض اتصالات TLS الخاصة به.

معالجة الشركة

يتضمن التطبيق الآن إعدادات لأمن الشبكة لا تثق إلا بشهادات النظام، وتمنع الاتصالات غير المشفّرة، وتحدد مجموعة فعلية من البصمات المثبّتة لنطاقه. نُفذ هذا الإصلاح في مرحلة مبكرة، وأكدت وجوده بنفسي في التطبيق المنشور.

بشأن تقدير الخطورة

لماذا لا تجد هنا تصنيفًا مرتفعًا للخطورة؟ لم يظهر المفتاح الثابت إلا في المسار الاحتياطي عند تعطل Keystore، وكان استغلاله يتطلب الوصول المحلي إلى الجهاز. أما غياب تثبيت بصمات الشهادات فكان يتطلب شهادة أجنبية مثبّتة على الجهاز. المسألتان حقيقيتان لكن نطاقهما محدد، وقد عولجتا. لذلك فالوصف الأدق من درجة مبالغ فيها هو: وصول محلي مرتبط بالجهاز، بلا هجوم عن بُعد.

التنسيق والإفصاح


إفصاح منسّق عبر BSI CERT-Bund وCERT/CC. يمكن تتبّع معالجة الشركة في الشيفرة المفتوحة. لأغراض البحث والدفاع.