หมวดหมู่ OWASP: MASVS-PLATFORM: การโต้ตอบกับแพลตฟอร์ม
ภาพรวม
แอป Android และระบบ Android สามารถใช้การออกอากาศเป็นระบบการรับส่งข้อความเพื่อแจ้งเตือนแอปอื่นๆ เกี่ยวกับเหตุการณ์ที่แอปเหล่านั้นอาจสนใจ การประกาศแบบติดหนึบเป็นการประกาศประเภทพิเศษซึ่งออบเจ็กต์ Intent ที่ส่งจะยังคงอยู่ในแคชหลังจากที่การประกาศเสร็จสมบูรณ์ ระบบอาจออกอากาศ Intent แบบเหนียวอีกครั้งไปยังการลงทะเบียนตัวรับในภายหลัง อย่างไรก็ตาม Sticky Broadcast 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 นั้นจะแทนที่อินสแตนซ์ก่อนหน้าที่มีการดำเนินการ ข้อมูล ประเภท ตัวระบุ คลาส และหมวดหมู่เดียวกันในแคชแบบเหนียว ดังนั้น ผู้โจมตีจึงสามารถเขียนทับข้อมูลเพิ่มเติมใน Sticky Intent จากแอปที่ถูกต้องได้อย่างง่ายดาย ซึ่งอาจทำให้มีการออกอากาศซ้ำไปยังผู้รับรายอื่นๆ
ระบบจะส่งการออกอากาศที่ส่งโดยใช้วิธี sendStickyOrderedBroadcast() ไปยังผู้รับ 1 รายในแต่ละครั้งเพื่อให้ผู้รับที่มีลำดับความสำคัญสูงกว่าสามารถดูการออกอากาศก่อนที่จะส่งไปยังผู้รับที่มีลำดับความสำคัญต่ำกว่า เมื่อตัวรับแต่ละตัวทำงานตามลำดับ ตัวรับจะส่งต่อผลลัพธ์ไปยังตัวรับถัดไปได้ เช่น โดยการเรียกใช้ setResultData() หรือยกเลิกการออกอากาศเพื่อป้องกันไม่ให้ตัวรับที่ตามมารับการออกอากาศ ผู้โจมตีที่รับการกระจายข้อมูลที่ติดหนึบตามลำดับจากแอปที่ถูกต้องสามารถสร้างตัวรับที่มีลำดับความสำคัญสูงเพื่อดัดแปลงข้อมูลผลการกระจายข้อมูลหรือหยุดการกระจายข้อมูลโดยสมบูรณ์
ผลกระทบ
ผลกระทบจะแตกต่างกันไปขึ้นอยู่กับวิธีใช้การออกอากาศแบบเหนียวหนึบและข้อมูลที่ส่งไปยังตัวรับการออกอากาศ โดยทั่วไป การใช้การออกอากาศแบบติดหนึบอาจทำให้ข้อมูลที่ละเอียดอ่อนรั่วไหล มีการดัดแปลงข้อมูล มีการเข้าถึงโดยไม่ได้รับอนุญาตเพื่อเรียกใช้ลักษณะการทำงานในแอปอื่น และเกิดการปฏิเสธการให้บริการ
การลดปัญหา
ไม่ควรใช้การออกอากาศแบบปักหมุด รูปแบบที่แนะนำคือการใช้การประกาศแบบไม่เหนียวหนึบกับกลไกอื่น เช่น ฐานข้อมูลในเครื่อง เพื่อดึงค่าปัจจุบันเมื่อใดก็ตามที่ต้องการ
นักพัฒนาแอปสามารถควบคุมผู้ที่รับการออกอากาศที่ไม่ติดหนึบได้โดยใช้สิทธิ์หรือโดยการตั้งค่าชื่อแพ็กเกจแอปพลิเคชันใน Intent นอกจากนี้ หากไม่จำเป็นต้องส่งการออกอากาศไปยังคอมโพเนนต์ภายนอกแอป ให้ใช้ LiveData ซึ่งใช้รูปแบบ Observer
ดูข้อมูลเพิ่มเติมเกี่ยวกับการรักษาความปลอดภัยของการออกอากาศได้ในหน้าภาพรวมของการออกอากาศ