การออกอากาศแบบติดหนึบ

หมวดหมู่ 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 ซึ่งใช้รูปแบบการสังเกตการณ์

ดูข้อมูลเพิ่มเติมเกี่ยวกับการรักษาความปลอดภัยของออกอากาศได้ในหน้าภาพรวมของออกอากาศ