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