מקלטי שידורים לא מאובטחים

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

סקירה כללית

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

הפגיעות מתייחסת בדרך כלל למקרים שבהם מקלט השידורים מיוצא שלא במכוון, או על ידי הגדרת android:exported="true" ב-AndroidManifest או על ידי יצירת מקלט שידורים באופן פרוגרמטי, מה שהופך את המקלט לציבורי כברירת מחדל. אם הרכיב לא מכיל מסנני Intent, ערך ברירת המחדל הוא "false", אבל אם הרכיב מכיל לפחות מסנן Intent אחד, ערך ברירת המחדל של android:exported הוא "true".

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

השפעה

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

אמצעי צמצום סיכונים

איך למנוע את הבעיה לחלוטין

כדי לפתור את הבעיה באופן מלא, מגדירים את exported ל-false:

<receiver android:name=".MyReceiver" android:exported="false">
    <intent-filter>
        <action android:name="com.example.myapp.MY_ACTION" />
    </intent-filter>
</receiver>

שימוש בשיחות ובשיחות חוזרות

אם השתמשתם ב-broadcast receivers למטרות פנימיות באפליקציה (למשל, התראה על השלמת אירוע), אתם יכולים לשנות את מבנה הקוד כך שיעביר קריאה חוזרת (callback) שתופעל אחרי השלמת האירוע.

פונקציית event listener להשלמת אירועים

Kotlin

interface EventCompletionListener {
    fun onEventComplete(data: String)
}

Java

public interface EventCompletionListener {
    public void onEventComplete(String data);
}
משימה מאובטחת

Kotlin

class SecureTask(private val listener: EventCompletionListener?) {
    fun executeTask() {
        // Do some work...

        // Notify that the event is complete
        listener?.onEventComplete("Some secure data")
    }
}

Java

public class SecureTask {

    final private EventCompletionListener listener;

    public SecureTask(EventCompletionListener listener) {
        this.listener = listener;
    }

    public void executeTask() {
        // Do some work...

        // Notify that the event is complete
        if (listener != null) {
            listener.onEventComplete("Some secure data");
        }
    }
}
פעילות ראשית

Kotlin

class MainActivity : AppCompatActivity(), EventCompletionListener {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val secureTask = SecureTask(this)
        secureTask.executeTask()
    }

    override fun onEventComplete(data: String) {
        // Handle event completion securely
        // ...
    }
}

Java

public class MainActivity extends AppCompatActivity implements EventCompletionListener {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        SecureTask secureTask = new SecureTask(this);
        secureTask.executeTask();
    }

    @Override
    public void onEventComplete(String data) {
        // Handle event completion securely
        // ...
    }
}

הגנה על מקלטי שידורים באמצעות הרשאות

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

משאבים