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

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

סקירה כללית

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

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

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

השפעה

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

פעולות מיטיגציה

איך להימנע מהבעיה לגמרי

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

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

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

אם השתמשתם במקלטי שידור למטרות פנימיות באפליקציה (למשל, התראה על השלמת אירוע), תוכלו לשנות את המבנה של הקוד כדי להעביר קריאה חוזרת (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
        // ...
    }
}

אבטחה של מקלטי שידור באמצעות הרשאות

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

משאבים