หมวดหมู่ OWASP: MASVS-CODE: คุณภาพของโค้ด
ภาพรวม
การใช้ PendingIntent.getCreator*()
หรือ PendingIntent.getTarget*()
เพื่อพิจารณาว่าจะเชื่อถือผู้ส่ง PendingIntent หรือไม่จะทำให้เกิดความเสี่ยงในการถูกแสวงหาประโยชน์
PendingIntent.getCreator*()
หรือ
PendingIntent.getTarget*()
จะแสดงผู้สร้าง PendingIntent
ซึ่งไม่ตรงกับผู้ส่งเสมอไป แม้ว่าครีเอเตอร์อาจเป็นบุคคลที่เชื่อถือได้ แต่ไม่ควรเชื่อถือผู้ส่ง เนื่องจากผู้ส่งอาจเป็นแอปที่เป็นอันตราย
ซึ่งได้ PendingIntent ของแอปอื่นโดยใช้กลไกต่างๆ เช่น
- จาก
NotificationListenerService
- Use Case ที่ถูกต้องซึ่งเป็นส่วนหนึ่งของแอปที่มีช่องโหว่
ตัวอย่างการใช้ PendingIntent.getCreator*()
หรือ PendingIntent.getTarget*()
โดยชอบด้วยกฎหมายคือการแสดง
ไอคอนของแอปที่จะเริ่มต้นโดย PendingIntent
ผลกระทบ
การเชื่อถือผู้ส่ง PendingIntent เนื่องจากคุณได้ค้นหา (และเชื่อถือ) ครีเอเตอร์ อาจทำให้เกิดช่องโหว่ได้ หากแอปเชื่อถือผู้ส่ง PendingIntent ตามผู้สร้าง แล้วแชร์ตรรกะการตรวจสอบสิทธิ์หรือการให้สิทธิ์ เมื่อใดก็ตามที่ผู้ส่ง PendingIntent เป็นแอปที่เป็นอันตราย การดำเนินการนี้จะทำให้เกิดการข้ามการตรวจสอบสิทธิ์หรืออาจถึงขั้นมีการดำเนินการโค้ดจากระยะไกลโดยอิงตามอินพุตที่ไม่ถูกต้องและไม่น่าเชื่อถือ ทั้งนี้ขึ้นอยู่กับการใช้งานโค้ดของแอปพลิเคชันที่มีช่องโหว่
การลดปัญหา
แยกความแตกต่างระหว่างผู้ส่งกับครีเอเตอร์
ตรรกะการตรวจสอบสิทธิ์หรือการให้สิทธิ์ทุกประเภทที่ดำเนินการเมื่อได้รับ PendingIntent ต้องไม่ขึ้นอยู่กับสมมติฐานเกี่ยวกับผู้สร้าง PendingIntent ที่ระบุโดยใช้ PendingIntent.getCreator*()
หรือ PendingIntent.getTarget*()
ใช้วิธีอื่นในการตรวจสอบผู้โทร
หากต้องการตรวจสอบสิทธิ์ผู้โทร คุณควรใช้ Service หรือ ContentProvider แทนการใช้ PendingIntent เนื่องจากทั้ง 2 อย่างนี้อนุญาตให้ดึง UID ของผู้โทรด้วย Binder.getCallingUid() เมื่อคุณอยู่ในบริบทของการส่ง IPC ขาเข้า คุณจะค้นหา UID ได้ในภายหลังโดยใช้ PackageManager.getPackagesForUid()
อีกวิธีหนึ่งซึ่งใช้ได้ตั้งแต่ API ระดับ 34 คือการใช้ BroadcastReceiver.getSentFromUid() หรือ BroadcastReceiver.getSentFromPackage() หากผู้ส่งเลือกที่จะแชร์ ข้อมูลประจำตัวระหว่างการออกอากาศโดยใช้ BroadcastOptions.isShareIdentityEnabled()
คุณควรตรวจสอบเสมอว่าแพ็กเกจที่เรียกใช้มีลายเซ็นตามที่คาดไว้ เนื่องจากแพ็กเกจที่โหลดด้านข้างอาจมีชื่อแพ็กเกจที่ซ้อนทับกับแพ็กเกจจาก Play Store