קטגוריה ב-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
:
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);
הגנה שמוגדרת כברירת מחדל
ב-Android 16 נוסף פתרון מחמיר לאבטחה כברירת מחדל נגד נקודות חולשה של הפניות אוטומטיות (redirection) מסוג Intent
. ברוב המקרים, אפליקציות שמשתמשות בכוונות לא נתקלות בבעיות תאימות.
ביטול ההסכמה לטיפול בהפניות אוטומטיות של כוונה
ב-Android 16 נוסף ממשק API חדש שמאפשר לאפליקציות לבטל את ההצטרפות להגנות האבטחה במהלך ההשקה. יכול להיות שתצטרכו לעשות זאת במקרים ספציפיים שבהם התנהגות האבטחה שמוגדרת כברירת מחדל מפריעה לתרחישי שימוש חוקיים באפליקציה.
ב-Android 16, אפשר לבטל את ההצטרפות לאמצעי האבטחה באמצעות השיטה removeLaunchSecurityProtection()
באובייקט Intent
. לדוגמה:
val i = intent
val iSublevel: Intent? = i.getParcelableExtra("sub_intent")
iSublevel?.removeLaunchSecurityProtection() // Opt out from hardening
iSublevel?.let { startActivity(it) }
טעויות נפוצות
- בדיקה אם
getCallingActivity()
מחזירה ערך שאינו null. אפליקציות זדוניות עלולות לספק ערך null לפונקציה הזו. - בהנחה ש-
checkCallingPermission()
פועלת בכל ההקשרים, או שהשיטה מפעילה חריגה כשהיא למעשה מחזירה מספר שלם.
תכונות לניפוי באגים
באפליקציות שמטרגטות ל-Android 12 (רמת API 31) ואילך, אפשר להפעיל תכונה לניפוי באגים שתעזור לכם לזהות במקרים מסוימים אם האפליקציה מבצעת הפעלה לא בטוחה של כוונה (intent).
אם האפליקציה מבצעת את שתי הפעולות הבאות, המערכת מזהה הפעלה לא בטוחה של כוונה, ונגרמת הפרה של StrictMode
:
- האפליקציה מפרקת את ה-intent המוטמע מהפרטים הנוספים של ה-intent שנשלח.
- האפליקציה מפעילה מיד רכיב של האפליקציה באמצעות הכוונה ההטמעתית הזו, למשל העברת הכוונה אל
startActivity()
,startService()
אוbindService()
.