หมวดหมู่ OWASP: MASVS-PLATFORM: การโต้ตอบกับแพลตฟอร์ม
ภาพรวม
สิทธิ์ของ Android คือตัวระบุสตริงที่ประกาศไว้ในไฟล์ Manifest ของแอปเพื่อขอเข้าถึงข้อมูลหรือการดำเนินการที่จำกัด ซึ่งเฟรมเวิร์กของ Android จะบังคับใช้ในรันไทม์
ระดับสิทธิ์ของ Android บ่งบอกถึงความเสี่ยงที่อาจเกิดขึ้นซึ่งเกี่ยวข้องกับ สิทธิ์
- ปกติ: สิทธิ์ที่มีความเสี่ยงต่ำ ซึ่งระบบจะให้โดยอัตโนมัติในเวลาที่ติดตั้ง
- อันตราย: สิทธิ์ที่มีความเสี่ยงสูงซึ่งอาจอนุญาตให้เข้าถึงข้อมูลผู้ใช้ที่ละเอียดอ่อน โดยต้องให้ผู้ใช้ให้ความยินยอมอย่างชัดแจ้งในรันไทม์
- ลายเซ็น: ระบบจะให้สิทธิ์นี้เฉพาะแอปที่ลงชื่อด้วยใบรับรองเดียวกันกับ แอปที่ประกาศสิทธิ์ โดยมักใช้กับแอปของระบบหรือการโต้ตอบ ระหว่างแอปจากนักพัฒนาแอปคนเดียวกัน
ช่องโหว่ที่เกี่ยวข้องกับการควบคุมการเข้าถึงตามสิทธิ์จะเกิดขึ้นเมื่อคอมโพเนนต์ของแอป (เช่น กิจกรรม ตัวรับสัญญาณ ผู้ให้บริการเนื้อหา หรือ บริการ) ตรงตามเกณฑ์ทั้งหมดต่อไปนี้
- คอมโพเนนต์ไม่ได้เชื่อมโยงกับ
android:permissionใดๆ ในManifest - คอมโพเนนต์ทำงานที่ละเอียดอ่อนซึ่งมีสิทธิ์ที่ผู้ใช้ได้อนุมัติแล้ว
- คอมโพเนนต์ถูกส่งออก
- คอมโพเนนต์ไม่ได้ทำการตรวจสอบสิทธิ์ด้วยตนเอง (ระดับ Manifest หรือระดับโค้ด)
เมื่อเกิดเหตุการณ์นี้ขึ้น แอปที่เป็นอันตรายจะสามารถดำเนินการที่มีความละเอียดอ่อนได้โดยการใช้สิทธิ์ของคอมโพเนนต์ที่มีช่องโหว่ในทางที่ผิด ซึ่งเป็นการมอบสิทธิ์ของแอปที่มีช่องโหว่ให้กับแอปที่เป็นอันตราย
ผลกระทบ
การส่งออกคอมโพเนนต์ที่มีช่องโหว่อาจใช้เพื่อเข้าถึงแหล่งข้อมูลที่ละเอียดอ่อนหรือดำเนินการที่มีความละเอียดอ่อน ผลกระทบของลักษณะการทำงานที่ไม่พึงประสงค์นี้ขึ้นอยู่กับบริบทของคอมโพเนนต์ที่มีช่องโหว่และสิทธิ์ของคอมโพเนนต์
การบรรเทา
กำหนดให้ต้องมีสิทธิ์สำหรับงานที่ละเอียดอ่อน
เมื่อส่งออกคอมโพเนนต์ที่มีสิทธิ์ที่ละเอียดอ่อน ให้กำหนดให้ต้องมีสิทธิ์เดียวกันสำหรับคำขอขาเข้า IDE ของ Android Studio มีการตรวจสอบ Lint สำหรับ ตัวรับสัญญาณ และ บริการ เพื่อตรวจหาช่องโหว่ นี้และแนะนำให้กำหนดให้ต้องมีสิทธิ์ที่เหมาะสม
นักพัฒนาแอปสามารถกำหนดให้ต้องมีสิทธิ์สำหรับคำขอขาเข้าได้โดยการประกาศสิทธิ์ในไฟล์ Manifest หรือที่ระดับโค้ดเมื่อใช้งานบริการ ดังตัวอย่างต่อไปนี้
Xml
<manifest ...>
<uses-permission android:name="android.permission.READ_CONTACTS" />
<application ...>
<service android:name=".MyExportService"
android:exported="true"
android:permission="android.permission.READ_CONTACTS" />
</application>
</manifest>
Kotlin
class MyExportService : Service() {
private val binder = MyExportBinder()
override fun onBind(intent: Intent): IBinder? {
// Enforce calling app has the required permission
enforceCallingPermission(Manifest.permission.READ_CONTACTS, "Calling app doesn't have READ_CONTACTS permission.")
// Permission is enforced, proceed with export logic
return binder
}
// Inner class for your Binder implementation
private inner class MyExportBinder : Binder() {
// Permission is enforced, proceed with export logic
}
}
Java
public class MyExportService extends Service {
@Override
public IBinder onBind(Intent intent) {
// Enforce calling app has the required permission
enforceCallingPermission(Manifest.permission.READ_CONTACTS, "Calling app doesn't have READ_CONTACTS permission.");
return binder;
}
// Inner class for your Binder implementation
private class MyExportBinder extends Binder {
// Permission is enforced, proceed with export logic
}
}
อย่าส่งออกคอมโพเนนต์
หลีกเลี่ยงการส่งออกคอมโพเนนต์ที่มีสิทธิ์เข้าถึงแหล่งข้อมูลที่ละเอียดอ่อน เว้นแต่จะจำเป็นอย่างยิ่ง คุณทำได้โดยตั้งค่า android:exported ในไฟล์ Manifest เป็น false สำหรับคอมโพเนนต์ ตั้งแต่ ระดับ API 31 ขึ้นไป ระบบจะตั้งค่าแอตทริบิวต์นี้เป็น false โดยค่าเริ่มต้น
Xml
<activity
android:name=".MyActivity"
android:exported="false"/>
ใช้สิทธิ์ตามลายเซ็น
เมื่อแชร์ข้อมูลระหว่างแอป 2 แอปที่คุณควบคุมหรือเป็นเจ้าของ ให้ใช้สิทธิ์ตามลายเซ็น สิทธิ์เหล่านี้ไม่จำเป็นต้องให้ผู้ใช้ยืนยัน แต่จะตรวจสอบว่าแอปที่เข้าถึงข้อมูลลงชื่อด้วยคีย์การลงชื่อเดียวกัน การตั้งค่านี้มอบประสบการณ์การใช้งานที่ราบรื่นและปลอดภัยยิ่งขึ้น หากคุณประกาศ สิทธิ์ที่กำหนดเอง โปรดพิจารณาหลักเกณฑ์ด้านความปลอดภัยที่เกี่ยวข้อง
Xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.myapp">
<permission android:name="my_custom_permission_name"
android:protectionLevel="signature" />
ปลายทางแบบงานเดียว
ใช้งานแอปโดยทำตามหลักการออกแบบการแยกความกังวล อุปกรณ์ปลายทางแต่ละรายการควรทำงานเฉพาะเจาะจงเพียงเล็กน้อยโดยมีสิทธิ์เฉพาะ แนวทางปฏิบัติที่ดีในการออกแบบนี้ยังช่วยให้นักพัฒนาแอปใช้สิทธิ์แบบละเอียดสำหรับปลายทางแต่ละรายการได้ด้วย เช่น หลีกเลี่ยงการสร้างปลายทางเดียวที่ให้บริการทั้งปฏิทินและรายชื่อติดต่อ
แหล่งข้อมูล
- Android Access to app protected components จากบล็อก Oversecured
- แนวทางปฏิบัติแนะนำสำหรับผู้ให้บริการเนื้อหา
- สิทธิ์รันไทม์ (อันตราย)
- หลักการออกแบบการแยกความกังวล
- เอกสารประกอบเกี่ยวกับสิทธิ์ของ Android
- เคล็ดลับความปลอดภัยสำหรับตัวรับสัญญาณการออกอากาศของ Android
- เคล็ดลับความปลอดภัยสำหรับบริการของ Android
- Android 12 (API 31) ตั้งค่าเริ่มต้นของการส่งออกเป็น "false"
- การตรวจสอบ Lint: ไม่ควรส่งออก PreferenceActivity ที่ส่งออก
- การตรวจสอบ Lint: ตัวรับสัญญาณที่ส่งออกไม่จำเป็นต้องมีสิทธิ์
- การตรวจสอบ Lint: บริการที่ส่งออกไม่จำเป็นต้องมีสิทธิ์