หมวดหมู่ 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 ไปยังคอมโพเนนต์ที่ได้รับการปกป้องของแอปจากบล็อก Oversecured
- แนวทางปฏิบัติแนะนำสำหรับผู้ให้บริการเนื้อหา
- สิทธิ์รันไทม์ (อันตราย)
- หลักการออกแบบการแยกข้อกังวล
- เอกสารประกอบเกี่ยวกับสิทธิ์ของ Android
- เคล็ดลับด้านความปลอดภัยสำหรับเครื่องรับสัญญาณออกอากาศ Android
- เคล็ดลับด้านความปลอดภัยของบริการ Android
- Android 12 (API 31) ส่งออกค่าเริ่มต้นเป็น "false"
- การตรวจสอบ Lint: ไม่ควรส่งออก PreferenceActivity ที่ส่งออก
- การตรวจสอบ Lint: ผู้รับที่ส่งออกไม่จําเป็นต้องได้รับสิทธิ์
- การตรวจสอบ Lint: บริการที่ส่งออกไม่จําเป็นต้องขอสิทธิ์