การออกอากาศแบบติดหนึบ
จัดทุกอย่างให้เป็นระเบียบอยู่เสมอด้วยคอลเล็กชัน
บันทึกและจัดหมวดหมู่เนื้อหาตามค่ากำหนดของคุณ
หมวดหมู่ OWASP: MASVS-PLATFORM: การโต้ตอบกับแพลตฟอร์ม
ภาพรวม
แอป Android และระบบ Android สามารถใช้การออกอากาศเป็นระบบการรับส่งข้อความเพื่อแจ้งให้แอปอื่นๆ ทราบเกี่ยวกับเหตุการณ์ที่อาจสนใจ การประกาศแบบติดหนึบเป็นการประกาศประเภทพิเศษที่ออบเจ็กต์ Intent ที่ส่งจะยังคงอยู่ในแคชหลังจากการประกาศเสร็จสมบูรณ์ ระบบอาจออกอากาศ Intent แบบติดหนึบอีกครั้งสำหรับการลงทะเบียนผู้รับในภายหลัง แต่ API การออกอากาศแบบติดหนึบมีข้อบกพร่องด้านความปลอดภัยหลายประการ เราจึงเลิกใช้งานใน Android 5.0 (API ระดับ 21)
ทุกคนสามารถเข้าถึงการออกอากาศแบบปักหมุดได้
คุณจะจำกัดการออกอากาศแบบติดหนึบไว้สำหรับผู้รับที่มีสิทธิ์บางอย่างไม่ได้ ดังนั้นจึงไม่เหมาะสำหรับการออกอากาศข้อมูลที่ละเอียดอ่อน คุณอาจคิดว่าการระบุชื่อแพ็กเกจแอปพลิเคชันในIntent
การออกอากาศจะจํากัดชุดBroadcastReceivers
Kotlin
val intent = Intent("com.example.NOTIFY").apply {
setPackage("com.example.myapp")
}
applicationContext.sendBroadcast(intent)
Java
Intent intent = new Intent("com.example.NOTIFY");
intent.setPackage("com.example.myapp");
getApplicationContext().sendBroadcast(intent);
ในตัวอย่างนี้ เฉพาะผู้รับในแพ็กเกจ com.example.myapp
เท่านั้นที่จะได้รับ Intent เมื่อมีการออกอากาศ อย่างไรก็ตาม ระบบจะไม่ใช้ตัวกรองชื่อแพ็กเกจเมื่อมีการออกอากาศ Intent อีกครั้งจากแคชที่ติดหนึบ เมื่อลงทะเบียนตัวรับโดยใช้เมธอด registerReceiver()
ระบบจะออกอากาศ Intent ทั้งหมดในแคชที่ติดหนึบซึ่งตรงกับตัวกรองที่ระบุไปยังตัวรับอีกครั้ง โดยไม่คำนึงถึงชื่อแพ็กเกจของตัวรับ
ทุกคนส่งการกระจายข้อมูลที่ติดหนึบได้
หากต้องการส่งการประกาศแบบติดหนึบ แอปจะต้องมีสิทธิ์ android.permission.BROADCAST_STICKY
เท่านั้น ซึ่งจะได้รับโดยอัตโนมัติเมื่อติดตั้งแอป ดังนั้น ผู้โจมตีสามารถส่ง Intent ไปยังผู้รับรายใดก็ได้ ซึ่งอาจทำให้ได้รับสิทธิ์เข้าถึงแอปอื่นโดยไม่ได้รับอนุญาต ผู้รับการออกอากาศสามารถจำกัดผู้ส่งให้เป็นผู้ที่มีสิทธิ์บางอย่างได้ อย่างไรก็ตาม การทำเช่นนี้จะทำให้ผู้รับไม่สามารถรับการออกอากาศจากแคชที่ติดหนึบได้ เนื่องจากไม่มีการส่งแคชเหล่านั้นในบริบทของข้อมูลประจำตัวของแอปใดๆ และไม่มีการออกอากาศด้วยสิทธิ์ใดๆ
ทุกคนแก้ไขการออกอากาศที่ติดอยู่ได้
เมื่อ Intent เป็นส่วนหนึ่งของการออกอากาศแบบคงที่ Intent นั้นจะแทนที่อินสแตนซ์ก่อนหน้าซึ่งมีการดำเนินการ ข้อมูล ประเภท ตัวระบุ คลาส และหมวดหมู่เดียวกันในแคชแบบคงที่ ดังนั้น ผู้โจมตีสามารถเขียนทับข้อมูลเพิ่มเติมใน Intent แบบติดหนึบจากแอปที่ถูกต้องได้ง่ายๆ ซึ่งอาจมีการออกอากาศไปยังผู้รับรายอื่นอีกครั้ง
ระบบจะส่งการออกอากาศที่ส่งโดยใช้เมธอด sendStickyOrderedBroadcast()
ไปยังผู้รับ 1 รายต่อครั้งเพื่อให้ผู้รับที่มีลำดับความสำคัญสูงกว่าใช้การออกอากาศได้ก่อนที่จะส่งไปยังผู้รับที่มีลำดับความสำคัญต่ำกว่า เมื่อตัวรับแต่ละตัวดำเนินการตามลำดับ ตัวรับสามารถส่งต่อผลลัพธ์ไปยังตัวรับถัดไป เช่น โดยการเรียกใช้ setResultData()
หรือยกเลิกการออกอากาศเพื่อป้องกันไม่ให้ตัวรับที่ตามมารับการออกอากาศ ผู้โจมตีที่รับการกระจายข้อมูลที่ติดหนึบตามลําดับจากแอปที่ถูกต้องสามารถสร้างตัวรับที่มีลําดับความสําคัญสูงเพื่อแทรกแซงข้อมูลผลการกระจายข้อมูลหรือยกเลิกการกระจายข้อมูลโดยสิ้นเชิง
ผลกระทบ
ผลลัพธ์จะแตกต่างกันไปตามวิธีใช้การออกอากาศแบบติดหนึบและข้อมูลที่ส่งไปยังตัวรับการออกอากาศ โดยทั่วไปแล้ว การใช้การออกอากาศแบบติดหนึบอาจทําให้ข้อมูลที่มีความละเอียดอ่อนถูกเปิดเผย การดัดแปลงข้อมูล การเข้าถึงที่ไม่ได้รับอนุญาตเพื่อดําเนินการในแอปอื่น และการปฏิเสธการให้บริการ
การลดปัญหา
ไม่ควรใช้การออกอากาศแบบติดอยู่ รูปแบบที่แนะนําคือการใช้การออกอากาศแบบไม่ติดหนึบกับกลไกอื่น เช่น ฐานข้อมูลในเครื่อง เพื่อดึงค่าปัจจุบันเมื่อใดก็ตามที่ต้องการ
นักพัฒนาแอปสามารถควบคุมผู้ที่สามารถรับการออกอากาศแบบไม่ติดหนึบได้โดยใช้สิทธิ์ หรือกำหนดชื่อแพ็กเกจแอปพลิเคชันใน Intent นอกจากนี้ หากไม่จําเป็นต้องส่งการออกอากาศไปยังคอมโพเนนต์นอกแอป ให้ใช้ LiveData
ซึ่งใช้รูปแบบการสังเกตการณ์
ดูข้อมูลเพิ่มเติมเกี่ยวกับการรักษาความปลอดภัยของออกอากาศได้ในหน้าภาพรวมของออกอากาศ
ตัวอย่างเนื้อหาและโค้ดในหน้าเว็บนี้ขึ้นอยู่กับใบอนุญาตที่อธิบายไว้ในใบอนุญาตการใช้เนื้อหา Java และ OpenJDK เป็นเครื่องหมายการค้าหรือเครื่องหมายการค้าจดทะเบียนของ Oracle และ/หรือบริษัทในเครือ
อัปเดตล่าสุด 2025-07-26 UTC
[null,null,["อัปเดตล่าสุด 2025-07-26 UTC"],[],[],null,["# Sticky Broadcasts\n\n\u003cbr /\u003e\n\n**OWASP category:** [MASVS-PLATFORM: Platform Interaction](https://mas.owasp.org/MASVS/09-MASVS-PLATFORM)\n\nOverview\n--------\n\nAndroid apps and the Android system can use broadcasts as a messaging system to notify other apps of events that they might be interested in. *Sticky broadcasts* are a special type of broadcast for which the sent intent object(s) remains in the cache after the broadcast is complete. The system may re-broadcast sticky intents to later registrations of receivers. Unfortunately, the sticky broadcasts API suffers from a number of security-related shortcomings, which is why it was deprecated in Android 5.0 (API level 21).\n\n### Anyone can access sticky broadcasts\n\nSticky broadcasts cannot be restricted to receivers that hold certain permissions. Therefore, they aren't suitable for broadcasting sensitive information. It might be tempting to think that specifying the [application package name](/reference/android/content/Intent#setPackage(java.lang.String)) on the broadcast `Intent` limits the set of `BroadcastReceivers`: \n\n### Kotlin\n\n val intent = Intent(\"com.example.NOTIFY\").apply {\n setPackage(\"com.example.myapp\")\n }\n applicationContext.sendBroadcast(intent)\n\n### Java\n\n Intent intent = new Intent(\"com.example.NOTIFY\");\n intent.setPackage(\"com.example.myapp\");\n getApplicationContext().sendBroadcast(intent);\n\nIn the example, only receivers in the `com.example.myapp` package receive the intent when the broadcast is sent. However, the package name filter isn't applied when the Intent is re-broadcast from the sticky cache. When registering a receiver using the [`registerReceiver()`](/reference/android/content/Context#registerReceiver(android.content.BroadcastReceiver,%20android.content.IntentFilter)) method, all intents in the sticky cache that match the specified filter are re-broadcast to the receiver regardless of the package name in which the receiver resides.\n\n### Anyone can send sticky broadcasts\n\nTo send sticky broadcasts, an app only requires the `android.permission.BROADCAST_STICKY` permission, which is granted automatically when the app is installed. Therefore, attackers can send any intent to any receiver, potentially gaining unauthorized access to another app. Broadcast receivers can restrict the senders to those holding a certain permission. However, by doing so, the receiver can't receive broadcasts from the sticky cache because those are not sent in the context of any app's identity and aren't broadcast with any permissions.\n\n### Anyone can modify sticky broadcasts\n\nWhen an intent is part of a sticky broadcast, that intent replaces any previous instance that has the same action, data, type, identifier, class, and categories in the sticky cache. Therefore, an attacker can trivially overwrite the extra data in a sticky intent from a legitimate app, which might then get re-broadcast to other receivers.\n\nBroadcasts sent using the [`sendStickyOrderedBroadcast()`](/reference/android/content/Context#sendStickyOrderedBroadcast(android.content.Intent,%20android.content.BroadcastReceiver,%20android.os.Handler,%20int,%20java.lang.String,%20android.os.Bundle)) method are delivered to one receiver at a time to allow receivers with higher priority to consume the broadcast before it's delivered to receivers with lower priority. As each receiver executes in turn, it can propagate a result to the next receiver, such as by calling [`setResultData()`](/reference/android/content/BroadcastReceiver#setResultData(java.lang.String)), or it can [abort the broadcast](/reference/android/content/BroadcastReceiver#abortBroadcast()), preventing subsequent receivers from receiving the broadcast. An attacker that can receive sticky ordered broadcasts from a legitimate app can create a high-priority receiver to tamper with the broadcast result data or drop broadcasts completely.\n\nImpact\n------\n\nImpact varies depending on how sticky broadcasts are used and what data is passed to the broadcast receivers. Generally speaking, use of sticky broadcasts can lead to sensitive data exposure, data tampering, unauthorized access to execute behavior in another app, and denial of service.\n\nMitigations\n-----------\n\nSticky broadcasts shouldn't be used. The recommended pattern is to use non-sticky broadcasts with another mechanism, such as a local database, to retrieve the current value whenever desired.\n\nDevelopers can control who can receive non-sticky broadcasts using [permissions](/guide/components/broadcasts#restrict-broadcasts-permissions) or by setting the [application package name](/reference/android/content/Intent#setPackage(java.lang.String)) on the intent. Furthermore, if a broadcast doesn't need to be sent to components outside of an app, use [`LiveData`](/reference/androidx/lifecycle/LiveData), which implements the [observer pattern](https://en.wikipedia.org/wiki/Observer_pattern).\n\nMore information about securing broadcasts can be found on the [broadcasts overview](/guide/components/broadcasts#security-and-best-practices) page."]]