מקלטי שידורים לא מאובטחים
קל לארגן דפים בעזרת אוספים
אפשר לשמור ולסווג תוכן על סמך ההעדפות שלך.
קטגוריה ב-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
// ...
}
}
אבטחה של מקלטי שידור באמצעות הרשאות
כדאי לרשום מקבלי נתונים דינמיים רק לשידורים מוגנים (שידורים שרק אפליקציות ברמת המערכת יכולות לשלוח) או עם הרשאות ברמת החתימה שהוצהרו על ידי עצמן.
משאבים
דוגמאות התוכן והקוד שבדף הזה כפופות לרישיונות המפורטים בקטע רישיון לתוכן. Java ו-OpenJDK הם סימנים מסחריים או סימנים מסחריים רשומים של חברת Oracle ו/או של השותפים העצמאיים שלה.
עדכון אחרון: 2025-07-26 (שעון UTC).
[[["התוכן קל להבנה","easyToUnderstand","thumb-up"],["התוכן עזר לי לפתור בעיה","solvedMyProblem","thumb-up"],["סיבה אחרת","otherUp","thumb-up"]],[["חסרים לי מידע או פרטים","missingTheInformationINeed","thumb-down"],["התוכן מורכב מדי או עם יותר מדי שלבים","tooComplicatedTooManySteps","thumb-down"],["התוכן לא עדכני","outOfDate","thumb-down"],["בעיה בתרגום","translationIssue","thumb-down"],["בעיה בדוגמאות/בקוד","samplesCodeIssue","thumb-down"],["סיבה אחרת","otherDown","thumb-down"]],["עדכון אחרון: 2025-07-26 (שעון UTC)."],[],[],null,["# Insecure broadcast receivers\n\n\u003cbr /\u003e\n\n**OWASP category:** [MASVS-PLATFORM: Platform Interaction](https://mas.owasp.org/MASVS/09-MASVS-PLATFORM)\n\nOverview\n--------\n\nImproperly implemented broadcast receivers can allow an attacker to send a\nmalicious intent to make the vulnerable application perform actions which are\nnot intended for external callers.\n\nThe vulnerability generally refers to instances where the broadcast receiver is\nunintentionally exported, either by setting [`android:exported=\"true\"`](/guide/topics/manifest/receiver-element#exported) in\nthe AndroidManifest or by creating a broadcast receiver programmatically which\nmakes the receiver public by default. If the receiver doesn't contain any intent\nfilters the default value is `\"false\"` but if the receiver contains at least one\nintent filter the default value of android:exported is `\"true\"`.\n\nIntentionally exported broadcast receivers without proper access control can be\nabused if the developer did not intend for it to be called by all applications.\n\nImpact\n------\n\nInsecurely implemented broadcast receivers can be abused by an attacker to gain\nunauthorized access to execute behavior in the application that the developer\ndid not mean to expose to third parties.\n\nMitigations\n-----------\n\n### Avoid the problem entirely\n\nTo resolve the dilemma entirely, set `exported` to `false`: \n\n \u003creceiver android:name=\".MyReceiver\" android:exported=\"false\"\u003e\n \u003cintent-filter\u003e\n \u003caction android:name=\"com.example.myapp.MY_ACTION\" /\u003e\n \u003c/intent-filter\u003e\n \u003c/receiver\u003e\n\n### Use calls and callbacks\n\nIn the case you used broadcast receivers for internal app purposes (ie. event\ncompletion notification), you can restructure your code to pass a callback that\nwould fire after event completion instead.\n\n###### Event completion listener\n\n### Kotlin\n\n interface EventCompletionListener {\n fun onEventComplete(data: String)\n }\n\n### Java\n\n public interface EventCompletionListener {\n public void onEventComplete(String data);\n }\n\n###### Secure task\n\n### Kotlin\n\n class SecureTask(private val listener: EventCompletionListener?) {\n fun executeTask() {\n // Do some work...\n\n // Notify that the event is complete\n listener?.onEventComplete(\"Some secure data\")\n }\n }\n\n### Java\n\n public class SecureTask {\n\n final private EventCompletionListener listener;\n\n public SecureTask(EventCompletionListener listener) {\n this.listener = listener;\n }\n\n public void executeTask() {\n // Do some work...\n\n // Notify that the event is complete\n if (listener != null) {\n listener.onEventComplete(\"Some secure data\");\n }\n }\n }\n\n###### Main activity\n\n### Kotlin\n\n class MainActivity : AppCompatActivity(), EventCompletionListener {\n override fun onCreate(savedInstanceState: Bundle?) {\n super.onCreate(savedInstanceState)\n setContentView(R.layout.activity_main)\n\n val secureTask = SecureTask(this)\n secureTask.executeTask()\n }\n\n override fun onEventComplete(data: String) {\n // Handle event completion securely\n // ...\n }\n }\n\n### Java\n\n public class MainActivity extends AppCompatActivity implements EventCompletionListener {\n\n @Override\n protected void onCreate(Bundle savedInstanceState) {\n super.onCreate(savedInstanceState);\n setContentView(R.layout.activity_main);\n\n SecureTask secureTask = new SecureTask(this);\n secureTask.executeTask();\n }\n\n @Override\n public void onEventComplete(String data) {\n // Handle event completion securely\n // ...\n }\n }\n\n### Secure broadcast receivers with permissions\n\nOnly register dynamic receivers for [protected broadcasts](/about/versions/12/reference/broadcast-intents-31) (broadcasts that\nonly system level applications can send) or with [self-declared signature level\npermissions](/guide/topics/manifest/permission-element#plevel).\n\nResources\n---------\n\n- [Exported Receiver Elements](/guide/topics/manifest/receiver-element#exported)\n- [Broadcast Receiver Permissions documentation](/guide/components/broadcasts#receiving-broadcasts-permissions)\n- [Protected Broadcast Intents](/about/versions/12/reference/broadcast-intents-31)"]]