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 giá trị nhận dạng chuỗi đượ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ế, do khung Android thực thi trong thời gian chạy.
Cấp độ quyền trên Android cho biết mức độ rủi ro tiềm ẩn liên quan đến quyền:
- Bình thường: Quyền có mức độ rủi ro thấp, được cấp tự động tại 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 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ác biện pháp kiểm soát quyền truy cập dựa trên quyền xảy ra khi một thành phần của ứng dụng (chẳng hạn như hoạt động, broadcast receiver, nhà cung cấp nội dung hoặc dịch vụ) đáp ứng tất cả các tiêu chí sau:
- Thành phần này không liên kết với bất kỳ
android:permission
nào trongManifest
; - Thành phần 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 thủ công nào (tệp kê khai hoặc cấp mã);
Khi điều này xảy ra, ứ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, chuyển tiếp các đặc quyền của ứng dụng dễ bị tấn công đến ứng dụng độc hại.
Tác động
Bạn có thể dùng tính năng xuất các thành phần dễ bị tấn công để có quyền 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 phụ 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 các quyền đó cho mọi yêu cầu đến. IDE Android Studio có tính năng kiểm tra tìm lỗi mã nguồn cho bộ thu và dịch vụ để 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ừ trường hợp 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. Từ API cấp 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 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 của một tác vụ
Triển khai ứng dụng 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 phân phát cả lịch và danh bạ.
Tài nguyên
- Quyền truy cập của Android vào các thành phần được bảo vệ của ứng dụng trên blog Oversecured
- Các phương pháp hay nhất dành cho nhà cung cấp nội dung
- Quyền khi bắt đầu chạy (Nguy hiểm)
- Nguyên tắc thiết kế Tách biệt vấn đề
- Tài liệu về quyền trên Android
- Mẹo bảo mật cho broadcast receiver trên Android
- Mẹo bảo mật cho dịch vụ Android
- Android 12 (API 31) đã xuất mặc định được đặt thành "false"
- Kiểm tra tìm lỗi mã nguồn: Không được xuất PreferenceActivity đã xuất
- Kiểm tra tìm lỗi mã nguồn: Trình nhận được xuất không yêu cầu quyền
- Kiểm tra tìm lỗi mã nguồn: Dịch vụ đã xuất không yêu cầu quyền