קטגוריה ב-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. כך הרכיב לא יוצא והכוונה של פעולת היעד לא משתנה.
אפליקציות יכולות לבדוק לאן מופנה Intent באמצעות שיטות כמו 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 נוסף פתרון לחיזוק האבטחה כברירת מחדל כדי למנוע ניצול לרעה של הפניות אוטומטיות.Intent ברוב המקרים, לא צפויות בעיות תאימות באפליקציות שמשתמשות ב-Intents.
ביטול ההסכמה לטיפול בהפניה אוטומטית של 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.
אם האפליקציה מבצעת את שתי הפעולות הבאות, המערכת מזהה הפעלה לא בטוחה של Intent, ומתרחשת הפרה של StrictMode:
- האפליקציה שלך מבטלת את האריזה של intent מוטבע מהתוספים של intent שנמסר.
- האפליקציה מפעילה באופן מיידי רכיב של אפליקציה באמצעות ה-Intent המקונן הזה, למשל מעבירה את ה-Intent אל
startActivity(), אלstartService()או אלbindService().