הפניה אוטומטית של Intent

קטגוריית OWASP: MASVS-PLATFORM: אינטראקציה בפלטפורמה

סקירה כללית

הפניה אוטומטית של Intent מתרחשת כשתוקף יכול לשלוט באופן חלקי או מלא בתוכן של Intent שמשמש להפעלת רכיב חדש בהקשר של אפליקציה פגיעה.

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

השפעה

ההשפעה יכולה להשתנות. תוקף עלול להריץ תכונות פנימיות באפליקציה הפגיעה, או לגשת לרכיבים פרטיים כמו אובייקטים של ContentProvider שלא מיוצאו.

פעולות מיטיגציה

באופן כללי, אל תחשפו תכונות שקשורות להפניה אוטומטית של כוונות מקוננות. במקרים שבהם אי אפשר להימנע מכך, יש להשתמש בשיטות ההפחתה הבאות:

  • עליכם לנקות את המידע בחבילה בצורה נכונה. חשוב לזכור לבדוק או למחוק את הדגלים (FLAG_GRANT_READ_URI_PERMISSION, FLAG_GRANT_WRITE_URI_PERMISSION, FLAG_GRANT_PERSISTABLE_URI_PERMISSION, and FLAG_GRANT_PREFIX_URI_PERMISSION), ולבדוק לאן הכוונה מפנה. IntentSanitizer יכול לעזור בתהליך הזה.
  • משתמשים באובייקטים מסוג PendingIntent. כך לא תוכלו לייצא את הרכיב, וכוונה הפעולה של היעד תהיה בלתי ניתנת לשינוי.

אפליקציות יכולות לבדוק לאן מתבצעת הפניה אוטומטית של כוונה באמצעות שיטות כמו ResolveActivity:

Kotlin

val intent = getIntent()
// Get the component name of the nested intent.
val forward = intent.getParcelableExtra<Parcelable>("key") as Intent
val name: ComponentName = forward.resolveActivity(packageManager)
// Check that the package name and class name contain the expected values.
if (name.packagename == "safe_package" && name.className == "safe_class") {
    // Redirect the nested intent.
    startActivity(forward)
}

Java

Intent intent = getIntent()
// Get the component name of the nested intent.
Intent forward = (Intent) intent.getParcelableExtra("key");
ComponentName name = forward.resolveActivity(getPackageManager());
// Check that the package name and class name contain the expected values.
if (name.getPackageName().equals("safe_package") &&
        name.getClassName().equals("safe_class")) {
    // Redirect the nested intent.
    startActivity(forward);
}

אפליקציות יכולות להשתמש ב-IntentSanitizer באמצעות לוגיקה דומה לזו:

Kotlin

val intent = IntentSanitizer.Builder()
     .allowComponent("com.example.ActivityA")
     .allowData("com.example")
     .allowType("text/plain")
     .build()
     .sanitizeByThrowing(intent)

Java

Intent intent = new  IntentSanitizer.Builder()
     .allowComponent("com.example.ActivityA")
     .allowData("com.example")
     .allowType("text/plain")
     .build()
     .sanitizeByThrowing(intent);

טעויות נפוצות

  • בדיקה אם getCallingActivity() מחזירה ערך שאינו null. אפליקציות זדוניות עלולות לספק ערך null לפונקציה הזו.
  • בהנחה ש-checkCallingPermission() פועלת בכל ההקשרים, או שה-method גורמת לחריגה כשהיא מחזירה בפועל מספר שלם.

תכונות לניפוי באגים

באפליקציות שמטרגטות ל-Android 12 (רמת API 31) ואילך, אפשר להפעיל תכונה לניפוי באגים שתעזור לכם לזהות במקרים מסוימים אם האפליקציה מבצעת הפעלה לא בטוחה של כוונה (intent).

אם האפליקציה מבצעת את שתי הפעולות הבאות, המערכת מזהה הפעלה לא בטוחה של כוונה, ונגרמת הפרה של StrictMode:

  • האפליקציה מפרקת את ה-intent המוטמע מהפרטים הנוספים של ה-intent שנשלח.
  • האפליקציה מפעילה באופן מיידי רכיב של האפליקציה באמצעות הכוונה ההטמעתית הזו, למשל העברת הכוונה אל startActivity(),‏ startService() או bindService().

משאבים