בקרת גישה מבוססת-הרשאות לרכיבים שמיוצאים

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

סקירה כללית

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

רמות ההרשאות ב-Android מציינות את הסיכון הפוטנציאלי שמשויך להרשאה:

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

נקודות חולשה שקשורות לאמצעי בקרת גישה שמבוססים על הרשאות מתרחשות כשהרכיב של האפליקציה (כמו פעילות, מקלט, ספק תוכן או שירות) עומד בכל הקריטריונים הבאים:

  • הרכיב לא משויך לאף android:permission ב-Manifest.
  • הרכיב מבצע משימה רגישה שעבורה קיימת הרשאה שהמשתמש כבר אישר.
  • הרכיב מיוצא.
  • הרכיב לא מבצע בדיקות הרשאה ידניות (ברמת המניפסט או ברמת הקוד).

במקרה כזה, אפליקציה זדונית יכולה לבצע פעולות רגישות על ידי ניצול לרעה של ההרשאות של הרכיב הפגיע, והעברת ההרשאות של האפליקציה הפגיעה לאפליקציה הזדונית.

השפעה

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

מיטיגציות

דרישה להרשאות לביצוע משימות רגישות

כשמייצאים רכיב עם הרשאות רגישות, צריך לתת את אותן ההרשאות לכל בקשה נכנסת. סביבת הפיתוח המשולבת (IDE) של Android Studio כוללת בדיקות איתור שגיאות בקוד (lint) למקלטים ולשירותים כדי לזהות את נקודת החולשה הזו ולהמליץ על הצורך בהרשאות המתאימות.

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

XML

<manifest ...>
    <uses-permission android:name="android.permission.READ_CONTACTS" />

    <application ...>
        <service android:name=".MyExportService"
                 android:exported="true"
                 android:permission="android.permission.READ_CONTACTS" />

        </application>
</manifest>

Kotlin

class MyExportService : Service() {

    private val binder = MyExportBinder()

    override fun onBind(intent: Intent): IBinder? {
        // Enforce calling app has the required permission
        enforceCallingPermission(Manifest.permission.READ_CONTACTS, "Calling app doesn't have READ_CONTACTS permission.")
        // Permission is enforced, proceed with export logic
        return binder
    }

    // Inner class for your Binder implementation
    private inner class MyExportBinder : Binder() {
        // Permission is enforced, proceed with export logic
    }
}

Java

public class MyExportService extends Service {

    @Override
    public IBinder onBind(Intent intent) {
        // Enforce calling app has the required permission
        enforceCallingPermission(Manifest.permission.READ_CONTACTS, "Calling app doesn't have READ_CONTACTS permission.");

        return binder;

    }

    // Inner class for your Binder implementation
    private class MyExportBinder extends Binder {
        // Permission is enforced, proceed with export logic

    }
}

לא מייצאים את הרכיב

הימנעו מייצוא רכיבים שיש להם גישה למשאבים רגישים, אלא אם יש צורך חיוני בכך. כדי לעשות זאת, צריך להגדיר את android:exported בקובץ Manifest כ-false עבור הרכיב. החל מרמת API 31 ואילך, המאפיין הזה מוגדר כברירת מחדל לערך false.

XML

<activity
    android:name=".MyActivity"
    android:exported="false"/>

החלת הרשאות המבוססות על חתימה

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

XML

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.myapp">
    <permission android:name="my_custom_permission_name"
                android:protectionLevel="signature" />

נקודות קצה למשימות בודדות

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

משאבים