Kiểm soát quyền truy cập dựa trên quyền vào các thành phần đã xuất

Danh mục OWASP: MASVS-PLATFORM: Tương tác với nền tảng

Tổng quan

Quyền trên Android là một chuỗi nhận dạng được khai báo trong tệp kê khai của ứng dụng để yêu cầu quyền truy cập vào dữ liệu hoặc hành động bị hạn chế, được khung Android thực thi trong thời gian chạy.

Các cấp độ quyền trên Android cho biết rủi ro tiềm ẩn liên quan đến quyền:

  • Thông thường: Quyền có rủi ro thấp, tự động được cấp vào thời điểm cài đặt
  • Nguy hiểm: Các quyền có mức độ rủi ro cao có thể cho phép truy cập vào dữ liệu nhạy cảm của người dùng, yêu cầu người dùng phê duyệt rõ ràng trong thời gian chạy
  • Chữ ký: Chỉ cấp cho các ứng dụng được ký bằng cùng một chứng chỉ với ứng dụng khai báo quyền, thường được dùng cho các ứng dụng hệ thống hoặc hoạt động tương tác giữa các ứng dụng của cùng một nhà phát triển

Các lỗ hổng liên quan đến cơ chế kiểm soát quyền truy cập dựa trên quyền xảy ra khi thành phần của ứng dụng (chẳng hạn như activity, receiver, content provider hoặc service) đáp ứng tất cả các tiêu chí sau:

  • Thành phần này không được liên kết với bất kỳ android:permission nào trong Manifest;
  • Thành phần này thực hiện một tác vụ nhạy cảm mà người dùng đã phê duyệt quyền;
  • Thành phần được xuất;
  • Thành phần này không thực hiện bất kỳ hoạt động kiểm tra quyền nào theo cách thủ công (cấp mã hoặc tệp kê khai);

Trong trường hợp này, một ứng dụng độc hại có thể thực hiện các hành động nhạy cảm bằng cách lợi dụng các đặc quyền của thành phần dễ bị tấn công, uỷ quyền các đặc quyền của ứng dụng dễ bị tấn công cho ứng dụng độc hại.

Tác động

Việc xuất các thành phần dễ bị tấn công có thể được dùng để truy cập vào các tài nguyên nhạy cảm hoặc thực hiện các hành động nhạy cảm. Mức độ tác động của hành vi không mong muốn này tuỳ thuộc vào ngữ cảnh của thành phần dễ bị tấn công và các đặc quyền của thành phần đó.

Giải pháp giảm thiểu

Yêu cầu cấp quyền cho các tác vụ nhạy cảm

Khi xuất một thành phần có các quyền nhạy cảm, hãy yêu cầu những quyền tương tự cho mọi yêu cầu đến. Môi trường phát triển tích hợp (IDE) Android Studio có các chế độ kiểm tra lint cho receiverservice để phát hiện lỗ hổng này và đề xuất yêu cầu các quyền thích hợp.

Nhà phát triển có thể yêu cầu cấp quyền cho các yêu cầu đến bằng cách khai báo các quyền đó trong tệp Manifest hoặc ở cấp mã khi triển khai dịch vụ, như trong các ví dụ sau.

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

    }
}

Không xuất thành phần

Tránh xuất các thành phần có quyền truy cập vào tài nguyên nhạy cảm, trừ phi thực sự cần thiết. Bạn có thể thực hiện việc này bằng cách đặt android:exported trong tệp Manifest thành false cho thành phần của mình. Kể từ cấp độ API 31 trở lên, thuộc tính này được đặt thành false theo mặc định.

XML

<activity
    android:name=".MyActivity"
    android:exported="false"/>

Áp dụng các quyền dựa trên chữ ký

Khi chia sẻ dữ liệu giữa hai ứng dụng mà bạn sở hữu hoặc có quyền kiểm soát, hãy sử dụng các quyền dựa trên chữ ký. Các quyền này không yêu cầu người dùng xác nhận và thay vào đó, hãy kiểm tra để đảm bảo rằng các ứng dụng truy cập vào dữ liệu đã được xác nhận bằng cùng một khoá ký. Chế độ thiết lập này mang đến trải nghiệm người dùng an toàn và đơn giản hơn. Nếu bạn khai báo các quyền tuỳ chỉnh, hãy cân nhắc các nguyên tắc bảo mật tương ứng.

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" />

Điểm cuối cho một tác vụ

Triển khai ứng dụng của bạn bằng cách tuân theo nguyên tắc thiết kế Tách biệt các mối quan ngại. Mỗi điểm cuối chỉ nên thực hiện một nhóm nhỏ các tác vụ cụ thể với các đặc quyền cụ thể. Phương pháp thiết kế hay này cũng cho phép nhà phát triển áp dụng các quyền chi tiết cho từng điểm cuối. Ví dụ: tránh tạo một điểm cuối duy nhất phục vụ cả lịch và danh bạ.

Tài nguyên