في انتظار المراجعة

فئة OWASP: MASVS-PLATFORM: Platform Interaction (التفاعل مع النظام الأساسي)

نظرة عامة

PendingIntent هو إشارة إلى رمز مفتاح يحفظه النظام. يمكن للتطبيق "أ" تمرير PendingIntent إلى التطبيق "ب" للسماح للتطبيق "ب" بتنفيذ إجراءات محدّدة مسبقًا نيابةً عن التطبيق "أ"، بغض النظر عمّا إذا كان التطبيق "أ" لا يزال قيد التشغيل.

الخطر: النوايا المعلّقة القابلة للتغيير

يمكن أن يكون PendingIntent قابلاً للتغيير، ما يعني أنّه يمكن للتطبيق "ب" تعديل النية الداخلية التي تحدّد الإجراء وفقًا للمنطق الموضّح في مستندات fillIn(). بعبارة أخرى، يمكن لتطبيق ضار تعديل الحقول غير المعبأة في PendingIntent والسماح بالوصول إلى مكوّنات التطبيق المعرض للاختراق والتي لم يتم تصديرها.

التأثير

يختلف تأثير هذه الثغرة الأمنية حسب تنفيذ الوظيفة المستهدفة غير المُصدَّرة في التطبيق.

إجراءات التخفيف

بنود عامة

تأكَّد من ضبط الإجراء والمكوِّن والحزمة لتجنُّب أسوأ الثغرات الأمنية:

Kotlin

val intent = Intent(intentAction)

// Or other component setting APIs e.g. setComponent, setClass
intent.setClassName(packageName, className)

PendingIntent pendingIntent =
    PendingIntent.getActivity(
        context,
        /* requestCode = */ 0,
        intent, /* flags = */ PendingIntent.FLAG_IMMUTABLE
    )

Java

Intent intent = new Intent(intentAction);

// Or other component setting APIs e.g. setComponent, setClass
intent.setClassName(packageName, className);

PendingIntent pendingIntent =
        PendingIntent.getActivity(
            getContext(),
            /* requestCode= */ 0,
            intent, /* flags= */ 0);

وضع العلامة IMMUTABLE

إذا كان تطبيقك يستهدف الإصدار 6 من نظام التشغيل Android (المستوى 23 من واجهة برمجة التطبيقات) أو الإصدارات الأحدث، عليك تحديد قابلية التغيّر. على سبيل المثال، يمكن إجراء ذلك باستخدام FLAG_IMMUTABLE لمنع تطبيق ضار من ملء الحقول غير المعبأة:

Kotlin

val pendingIntent =
    PendingIntent.getActivity(
        context,
        /* requestCode = */ 0,
        Intent(intentAction),
        PendingIntent.FLAG_IMMUTABLE)

Java

PendingIntent pendingIntent =
        PendingIntent.getActivity(
            getContext(),
            /* requestCode= */ 0,
            new Intent(intentAction),
            PendingIntent.FLAG_IMMUTABLE);

في الإصدار 11 من نظام التشغيل Android (المستوى 30 لواجهة برمجة التطبيقات) والإصدارات الأحدث، عليك تحديد الحقول التي تريد جعلها قابلة للتغيير، ما يقلل من الثغرات العرضية من هذا النوع.

المراجع


الخطر: إعادة تشغيل النوايا المعلّقة

يمكن إعادة تشغيل PendingIntent ما لم يتم ضبط العلامة FLAG_ONE_SHOT. من المهم استخدام FLAG_ONE_SHOT لتجنُّب هجمات إعادة التشغيل (تنفيذ إجراءات لا يمكن تكرارها).

التأثير

يختلف تأثير هذه الثغرة الأمنية حسب تنفيذ الطرف المستلِم للطلب. يمكن لتطبيق ضار يستغل PendingIntent تم إنشاؤه بدون ضبط العلامة FLAG_ONE_SHOT أن يرصد النية ويعيد استخدامها لتكرار الإجراءات التي من المفترض أن يتم إجراؤها مرة واحدة فقط.

إجراءات التخفيف

يجب استخدام العلامة FLAG_ONE_SHOT مع نوايا التنفيذ المعلّقة التي لا يُقصد إطلاقها عدة مرات لتجنُّب هجمات إعادة التشغيل.

Kotlin

val pendingIntent =
      PendingIntent.getActivity(
          context,
          /* requestCode = */ 0,
          Intent(intentAction),
          PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_ONE_SHOT)

Java

PendingIntent pendingIntent =
        PendingIntent.getActivity(
            getContext(),
            /* requestCode= */ 0,
            new Intent(intentAction),
            PendingIntent.FLAG_IMMUTABLE | PendingIntent.FLAG_ONE_SHOT);

المراجع


المراجع