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

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

סקירה כללית

הפניה אוטומטית של 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:

KotlinJava
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)
}
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 באמצעות לוגיקה דומה לזו:

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

הגנה שמוגדרת כברירת מחדל

  • ב-Android 16 מוצג פתרון מחמיר לאבטחה כברירת מחדל נגד ניצול לרעה של הפניות כוונות (Intent).

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

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

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

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

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

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

משאבים