مرحباً بالجميع ، أود اليوم أن أخبركم ببعض الخيارات لنقل البيانات بين تطبيقين لنظام أندرويد والنظر فيها من وجهة نظر أمنية. قررت أن أكتب هذا المقال لسببين. أولاً ، بدأت غالبًا في مواجهة نقص في فهم مطوري آليات العمل مع مكونات تطبيق android. الثانية - توقفت عن فهم الخيار الذي تقوم عليه هذه الآلية أو تلك بناءً على تطبيق الميزات وأردت أن أنقل كيف ينبغي أن ننظر إلى الحد الأدنى.
مهمة
لدينا تطبيقان يصلان إلى نفس واجهة برمجة التطبيقات. يمكن للعملاء الوصول إلى واجهة برمجة التطبيقات عن طريق الوصول إلى الرمز المميز (sessionId). يجب تنفيذ انتقال سلس من تطبيق إلى آخر. للقيام بذلك ، تحتاج إلى تلمس بينهما ، على سبيل المثال ، فليكن sessionId.
الخيار رقم 1: فك الارتباط العميق
الخيار الأكثر وضوحًا هو نقل الرمز المميز إلى Query DeepLink. سيبدو شيء مثل هذا:
slave://main?sessionId=686A885A4FB644053C584B9BE2A70C7D
في هذه الحالة ، سيتمكن المستلم من استخراج sessionId واستخدامه دون طلب إذن من المستخدم. من جانب المطور ، يبدو أن المهمة قد اكتملت ، لكن دعنا نحفر أعمق قليلاً.
Deeplink اختطاف
نظرًا لأن أي تطبيق يمكنه تسجيل مخطط tinkoff: // ، يمكن لنظام التشغيل فتح التطبيق الخاطئ. هذا ممكن بسبب حقيقة أنه لا يوجد تسجيل وقيود على استخدام المخططات. قد يسجل تطبيق ضار في تينكوف: / / مخطط واعتراض الطلب إلى تطبيق تينكوف وبدء نفسه. في هذه الحالة ، ستقع الجلسة في الأيدي الخطأ وسيتم اختراق حسابك. بالإضافة إلى ذلك ، يتيح لك DeepLink Hijacking إجراء التصيد الاحتيالي ، على سبيل المثال ، عرض الحقول لإدخال اسم المستخدم وكلمة المرور.
من الناحية النظرية ، تبدو العملية كما يلي:

هناك 2 حلول لهذه المشكلة. أولاً ، لم تعد تقنية AppLinks تسمح للمطورين بتخصيص المخطط ؛ بدلاً من ذلك ، يتم استخدام http / https. في هذه الحالة ، يأخذ نظام التشغيل الرابط slave.com/profile ويتصل بمضيف slave.com للتحقق منه. عنوان URL المقصود الثاني - بدلاً من استدعاء العبد: // ، الهدف: // يسمى ، حيث يتم تمرير المعرف الفريد للتطبيق الذي سيتم تشغيله. يبدو مثل هذا:
intent://main/#Intent;scheme=slave;package=com.example.slave.client.android;end"
في هذه الحالة ، لن يكون من الممكن اعتراض تشغيل التطبيق ، حيث تم تحديد حزمة محددة. ومع ذلك ، تظل المشكلة هي أنه يمكن للمستخدم تثبيت التطبيق من مصدر تابع لجهة أخرى بنفس الحزمة ، مثل الحزمة الخاصة بك. في هذه الحالة ، إذا لم يكن لديك تطبيق عبودي شرعي ، فسيقوم التطبيق الضار بتثبيت وتلقي الرمز المميز الخاص بك.
تثبيت الجلسة
هذا هو الهجوم الذي يجبر فيه المهاجم العميل على إنشاء جلسة مع البرنامج المستهدف باستخدام sessionId الذي يقدمه المهاجم. بمجرد مصادقة المستخدم ، سيتمكن المهاجم من استخدام هذا المعرّف المميز بالفعل لأغراضه الخاصة. يستغل الهجوم حقيقة أن البرنامج المستهدف يستخدم نفس الجلسة بعد تصعيد الامتياز.

كيف يبدو في حالتنا:
- المهاجم يحصل على جلسة مجهولة من التطبيق
- يلقي رسالة جميلة إلى الضحية نيابة عن البنك ، والتي يدعى فيها للذهاب إلى حسابه الشخصي
- عند النقر على الرابط ، نصل إلى DeepLink مع عبد الجلسة المهاجم: // main؟ sessionId = 686A885A4FB644053C584B9BE2A70C7D
- يأخذ تطبيق الهاتف المحمول جلسة ، ويدرك أنه لا يملك حقوقًا كافية ويطلب من المستخدم المصادقة
- يقوم المستخدم بتمريرها ، زادت الجلسة من الحقوق
- المستخدم في التطبيق ، مهاجم مع جلسة متميزة ، والربح
سيكون من الصحيح إصلاح هذا على واجهة برمجة التطبيقات ، وإصدار جلسة أخرى بعد تصعيد الامتياز ، لكننا نكتب تطبيقًا للجوال. وطريقتنا هي رفض نقل الرمز من السيد إلى العبد. بالإضافة إلى ذلك ، سيمنحنا ذلك حماية متعمقة ، وإذا حدث شيء ما على واجهة برمجة التطبيقات ولن تتغير الرموز عند زيادة الامتيازات ، فسيظل الهجوم مستحيلًا.
تسرب الطرف الثالث
ناقص آخر من هذا الخيار. يستخدم العديد من الأشخاص خدمات الجهات الخارجية لـ DeepLink نظرًا لراحة إنشاء الارتباطات والتحليلات وغيرها من الأشياء الرائعة. في هذه الحالة ، يمكنك ببساطة إعطاء الرمز المميز لشركة خارجية.
الخيار رقم 2: مزود المحتوى
كيف سنفعل ذلك؟ نحدد موفر المحتوى الرئيسي ونجعل العبد يذهب إلى موفر المحتوى هذا من أجل الرمز المميز.

وبالتالي ، نتخلص من خطر نقل الرمز المميز إلى التطبيق الخاطئ في حالة DeepLink Hijacking وجعل هجوم Session Session مستحيلاً. لكن لدينا مشاكل أخرى - في الإصدار الحالي ، بشكل عام ، يمكن لأي تطبيق طلب رمز مميز في أي وقت ، حتى لو لم نبدأ إطلاقه.
مستوى الحماية
في معظم الحالات ، تحتاج إلى التحقق من أن العبد موقّع على نفس المفتاح مثل الرئيسي ، أي أنه ينتمي إلى المؤلف نفسه. لهذه الحالة ، فإن مدير الحزم لديه طريقة checkSignatures التي تتحقق من توقيعات التطبيق. لاستخدام هذه الوظيفة ، تحتاج إلى إضافة إذن مع protectionLevel = "signature" في Content-Provider في بيان التطبيق:
<permission android:name="com.example.contentprovider.access" android:protectionLevel="signature"/> <application> <provider ... android:readPermission="com.example.contentprovider.access"> </application>
بالكاد سيتغير المخطط عن الشكل السابق ، فقط الضمان سيظهر أن التطبيقات التي تحمل توقيعًا من نفس المؤلف ستتمكن من الوصول إلى الرمز المميز.
حالة سباق الإذن
هناك ميزة واحدة غير سارة للغاية وهي أن أسماء الأذونات ليست فريدة من نوعها ، والتي يمكن استخدامها بواسطة تطبيق ضار وإذن تسجيل باسمنا و protectionLevel = "عادي" أمامنا. في هذه الحالة ، عند تثبيت تطبيقنا ، سيكون الإذن موجودًا بالفعل على نظام التشغيل ولن يتم الكتابة عليه. وبالتالي ، سيظل مزود المحتوى الخاص بنا بلا حماية وبإمكانية الوصول المصرح به من أي تطبيق.
تواقيع مختلفة
لسوء الحظ ، لا يتم توقيع التطبيقات دائمًا باستخدام نفس المفتاح ، على سبيل المثال ، يتم شراء بعض التطبيقات أو "تاريخياً" ، ولكن لا تزال هناك حاجة إلى انتقال سلس. في هذه الحالة ، نأخذ التحقق من التوقيع على أنفسنا.
كيف يمكن تنفيذ ذلك:
لدى Content-Provider طريقة getCallingPackage () ، والتي يمكننا من خلالها الحصول على packageId للتطبيق الذي تم تطبيقه على البيانات ، وباستخدام packageId يمكننا الحصول على قائمة التواقيع والتحقق منها مع تلك المضمّنة.
String pkg = this.getCallingPackage(); PackageInfo pkgInfo = pkgmgr.getPackageInfo(pkg, GET_SIGNATURES); Signatures[] signatures = pkgInfo.signatures; for (Signature sig: signatures) { if (sig.equals(TRUSTED_SIGNATURE)) {

يبدو أننا فعلنا كل شيء بشكل مثالي ، لكن لا.
معرف الضعف وهمية
المشكلة هي أنه عندما ينشئ Android سلسلة من الثقة ، فإن عملية التحقق تقارن فقط الموضوع ، ولا تتحقق من التوقيع في حقل موقِّع الشهادة. نتيجة لذلك ، يمكن للمهاجم إنشاء سلسلة من الثقة دون توقيع فعلي.
بسبب هذا الخطأ ، يتم إنشاء سلسلة شهادات غير صحيحة ، والتي قد تتضمن شهادات شرعية مضمنة في APK ، ولكن لا يتم استخدامها فعليًا للتوقيع على التطبيق. في النهاية ، سأترك رابطًا للالتزام الذي يعمل على إصلاح هذه الثغرة الأمنية. تم إصلاح المشكلة في نظام أندرويد 4.4 ، لذلك يمكننا فقط رفع مستوى API إلى 19.
النتائج
درسنا اليوم كيف ينبغي تحليل الميزات أثناء التطوير.
درسنا أيضًا خيارات نقل السر بين تطبيقين ، قمنا خلالها بتحليل مشاكل كل خيار وتوصلنا إلى طرق لتجنبها.
جميع التطبيقات الآمنة!
مراجع