การควบคุมการเข้าถึงตามสิทธิ์เข้าถึงคอมโพเนนต์ที่ส่งออก

หมวดหมู่ 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" />

ปลายทางแบบงานเดียว

ติดตั้งใช้งานแอปโดยทำตามหลักการการแยกข้อกังวลในการออกแบบ อุปกรณ์ปลายทางแต่ละเครื่องควรทํางานเฉพาะงานบางอย่างในชุดเล็กๆ ที่มีสิทธิ์เฉพาะ แนวทางปฏิบัติแนะนำด้านการออกแบบนี้ยังช่วยให้นักพัฒนาแอปใช้สิทธิ์แบบละเอียดสำหรับอุปกรณ์ปลายทางแต่ละเครื่องได้อีกด้วย เช่น หลีกเลี่ยงการสร้างปลายทางเดียวที่ให้บริการทั้งปฏิทินและรายชื่อติดต่อ

แหล่งข้อมูล