หมวดหมู่ 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
ซึ่งใช้รูปแบบการสังเกตการณ์
ดูข้อมูลเพิ่มเติมเกี่ยวกับการรักษาความปลอดภัยของออกอากาศได้ในหน้าภาพรวมของออกอากาศ