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:permissionnào trongManifest; - 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 receiver và service để 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
- Android Access to app protected components from the Oversecured blog
- Các phương pháp hay nhất dành cho nhà cung cấp nội dung
- Quyền trong thời gian chạy (nguy hiểm)
- Nguyên tắc thiết kế Phân tách tính năng
- Tài liệu về quyền trên Android
- Mẹo bảo mật về broadcast receiver trên Android
- Mẹo bảo mật cho các dịch vụ của Android
- Android 12 (API 31) đã xuất chế độ mặc định thành "false"
- Kiểm tra tìm lỗi mã nguồn: Không nên xuất Exported PreferenceActivity
- Kiểm tra tìm lỗi mã nguồn: Exported Receiver 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