Danh mục OWASP: MASVS-PLATFORM: Tương tác với nền tảng
Tổng quan
Chuyển hướng ý định xảy ra khi kẻ tấn công có thể kiểm soát một phần hoặc toàn bộ nội dung của ý định dùng để chạy một thành phần mới trong bối cảnh một ứng dụng dễ bị tấn công.
Bạn có thể cung cấp ý định dùng để chạy thành phần mới theo nhiều cách, thường là ý định chuyển đổi tuần tự trong trường extras
hoặc kết hợp với một chuỗi và được phân tích cú pháp. Việc kiểm soát một phần các tham số cũng có thể dẫn đến kết quả tương tự.
Tác động
Mức độ tác động có thể khác nhau. Kẻ tấn công có thể thực thi chức năng nội bộ trong ứng dụng dễ bị tấn công hoặc có thể truy cập vào các thành phần riêng tư như đối tượng ContentProvider chưa xuất.
Giải pháp giảm thiểu
Chung
Nhìn chung, đừng cung cấp chức năng liên quan đến việc chuyển hướng ý định lồng nhau. Trong trường hợp không thể tránh khỏi, hãy áp dụng các phương pháp giảm thiểu sau đây:
- Dọn dẹp thông tin đi kèm đúng cách. Bạn cần nhớ kiểm tra hoặc xoá cờ (
GRANT_URI_PERMISSIONS
) và kiểm tra vị trí mà ý định đang được chuyển hướng. IntentSanitizer có thể giúp bạn thực hiện quy trình này. - Sử dụng đối tượng
PendingIntent
. Điều này ngăn việc xuất thành phần và làm cho ý định của hành động mục tiêu không thể thay đổi được.
Các ứng dụng có thể kiểm tra vị trí mà một ý định đang được chuyển hướng bằng các phương thức như ResolveActivity
:
Kotlin
val intent = getIntent()
// Get the component name of the nested intent.
val forward = intent.getParcelableExtra<Parcelable>("key") as Intent
val name: ComponentName = forward.resolveActivity(packageManager)
// Check that the package name and class name contain the expected values.
if (name.packagename == "safe_package" && name.className == "safe_class") {
// Redirect the nested intent.
startActivity(forward)
}
Java
Intent intent = getIntent()
// Get the component name of the nested intent.
Intent forward = (Intent) intent.getParcelableExtra("key");
ComponentName name = forward.resolveActivity(getPackageManager());
// Check that the package name and class name contain the expected values.
if (name.getPackageName().equals("safe_package") &&
name.getClassName().equals("safe_class")) {
// Redirect the nested intent.
startActivity(forward);
}
Các ứng dụng có thể dùng IntentSanitizer theo logic tương tự như sau:
Kotlin
val intent = IntentSanitizer.Builder()
.allowComponent("com.example.ActivityA")
.allowData("com.example")
.allowType("text/plain")
.build()
.sanitizeByThrowing(intent)
Java
Intent intent = new IntentSanitizer.Builder()
.allowComponent("com.example.ActivityA")
.allowData("com.example")
.allowType("text/plain")
.build()
.sanitizeByThrowing(intent);
Lỗi thường gặp
- Kiểm tra xem
getCallingActivity()
có trả về một giá trị không rỗng hay không. Các ứng dụng độc hại có thể cung cấp giá trị rỗng cho hàm này. - Cho rằng
checkCallingPermission()
hoạt động trong mọi ngữ cảnh hoặc rằng phương thức này đưa ra ngoại lệ khi thực sự trả về một số nguyên.
Các tính năng gỡ lỗi
Đối với các ứng dụng nhắm mục tiêu Android 12 (API cấp 31) trở lên, bạn có thể bật tính năng gỡ lỗi để, trong một số trường hợp, giúp bạn phát hiện xem ứng dụng có đang khởi chạy một ý định theo cách không an toàn hay không.
Nếu ứng dụng thực hiện cả hai hành động sau đây, thì hệ thống sẽ phát hiện một lượt khởi chạy ý định theo cách không an toàn và một lỗi vi phạm StrictMode
xảy ra:
- Ứng dụng của bạn sẽ tách các ý định lồng nhau khỏi các thành phần đi kèm của ý định đã phân phối.
- Ứng dụng sẽ bắt đầu ngay một thành phần ứng dụng bằng cách dùng ý định lồng nhau đó, chẳng hạn như chuyển ý định đến
startActivity()
,startService()
hoặcbindService()
.
Tài nguyên
Đề xuất cho bạn
- Lưu ý: văn bản có đường liên kết sẽ hiện khi JavaScript tắt
- Ý định đang chờ xử lý