כוונות רכישה בהמתנה

קטגוריה ב-OWASP: MASVS-PLATFORM: Platform Interaction

סקירה כללית

PendingIntent הוא הפניה לאסימון שמתוחזק על ידי המערכת. אפליקציה א' יכולה להעביר PendingIntent לאפליקציה ב' כדי לאפשר לאפליקציה ב' לבצע פעולות מוגדרות מראש בשם אפליקציה א', בלי קשר לשאלה אם אפליקציה א' עדיין פעילה.

סיכון: כוונות בהמתנה שניתן לשנות

אובייקט PendingIntent יכול להיות ניתן לשינוי, כלומר אפליקציה ב' יכולה לעדכן את ה-Intent הפנימי שמציין את הפעולה, בהתאם ללוגיקה שמתוארת במסמכי התיעוד של 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

אם האפליקציה מטרגטת ל-Android 6 (רמת API ‏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);

ב-Android 11 (רמת API 30) ומעלה, צריך לציין אילו שדות יהיו ניתנים לשינוי, וכך לצמצם את הסיכון לפגיעות מקריות מסוג זה.

משאבים


סיכון: הפעלה חוזרת של כוונות בהמתנה

אפשר להפעיל מחדש PendingIntent, אלא אם הדגל FLAG_ONE_SHOT מוגדר. חשוב להשתמש ב-FLAG_ONE_SHOT כדי למנוע התקפות חוזרות (ביצוע פעולות שלא אמורות להיות ניתנות לחזרה).

השפעה

ההשפעה של נקודת החולשה הזו משתנה בהתאם להטמעה של קצה הקבלה של ה-Intent. אפליקציה זדונית שמנצלת PendingIntent שנוצר בלי להגדיר את הדגל FLAG_ONE_SHOT יכולה לתפוס את ה-Intent ולעשות בו שימוש חוזר כדי לחזור על פעולות שאפשר לבצע רק פעם אחת.

אמצעי צמצום סיכונים

ל-Pending Intent שלא מיועד להפעלה כמה פעמים צריך להוסיף את הדגל 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);

משאבים


משאבים