Ý định đang chờ xử lý
Sử dụng bộ sưu tập để sắp xếp ngăn nắp các trang
Lưu và phân loại nội dung dựa trên lựa chọn ưu tiên của bạn.
Danh mục OWASP: MASVS-PLATFORM: Tương tác với nền tảng
Tổng quan
PendingIntent
là mã tham chiếu đến mã thông báo do hệ thống duy trì. Ứng dụng A có thể chuyển một PendingIntent sang ứng dụng B để cho phép ứng dụng B thực thi các thao tác định sẵn thay cho ứng dụng A; bất kể ứng dụng A có còn hoạt động hay không.
Rủi ro: Ý định đang chờ xử lý có thể thay đổi
Một PendingIntent có thể thay đổi, nghĩa là ứng dụng B có thể cập nhật ý định bên trong chỉ định hành động theo logic đã mô tả trong tài liệu fillIn()
. Nói cách khác, một ứng dụng độc hại có thể sửa đổi các trường chưa được điền của PendingIntent. Các trường này có thể cho phép truy cập vào các thành phần không được xuất của ứng dụng dễ bị tấn công.
Tác động
Mức độ tác động của lỗ hổng bảo mật này sẽ khác nhau tuỳ thuộc vào việc triển khai chức năng chưa xuất được nhắm mục tiêu của ứng dụng.
Giải pháp giảm thiểu
Chung
Hãy đảm bảo bạn đã thiết lập hành động, thành phần và gói để tránh các lỗ hổng bảo mật nghiêm trọng nhất:
Kotlin
val intent = Intent(intentAction)
// Or other component setting APIs e.g. setComponent, setClass
intent.setClassName(packageName, className)
PendingIntent pendingIntent =
PendingIntent.getActivity(
context,
/* requestCode = */ 0,
intent, /* flags = */ PendingIntent.FLAG_IMMUTABLE
)
Java
Intent intent = new Intent(intentAction);
// Or other component setting APIs e.g. setComponent, setClass
intent.setClassName(packageName, className);
PendingIntent pendingIntent =
PendingIntent.getActivity(
getContext(),
/* requestCode= */ 0,
intent, /* flags= */ 0);
Cờ KHÔNG THỂ THAY ĐỔI
Nếu ứng dụng của bạn dành cho Android 6 (API cấp độ 23) trở lên, hãy chỉ định khả năng thay đổi. Ví dụ: bạn có thể thực hiện việc này bằng cách sử dụng FLAG_IMMUTABLE
để ngăn ứng dụng độc hại điền vào các trường chưa được điền:
Kotlin
val pendingIntent =
PendingIntent.getActivity(
context,
/* requestCode = */ 0,
Intent(intentAction),
PendingIntent.FLAG_IMMUTABLE)
Java
PendingIntent pendingIntent =
PendingIntent.getActivity(
getContext(),
/* requestCode= */ 0,
new Intent(intentAction),
PendingIntent.FLAG_IMMUTABLE);
Trên Android 11 (API cấp độ 30) trở lên, bạn phải chỉ định những trường cần thay đổi để giảm thiểu các lỗ hổng bảo mật vô tình thuộc loại này.
Tài nguyên
Rủi ro: Phát lại ý định đang chờ xử lý
Bạn có thể phát lại một PendingIntent trừ phi đã đặt cờ FLAG_ONE_SHOT. Bạn cần phải sử dụng cờ FLAG_ONE_SHOT để tránh các cuộc tấn công phát lại (thực hiện các hành động không nên lặp lại).
Tác động
Mức độ tác động của lỗ hổng bảo mật này sẽ khác nhau tuỳ thuộc vào việc triển khai quá trình kết thúc nhận ý định. Một ứng dụng độc hại khai thác một PendingIntent được tạo mà không đặt cờ FLAG_ONE_SHOT có thể thu thập và dùng lại ý định đó để lặp lại các hành động chỉ có thể thực hiện một lần.
Giải pháp giảm thiểu
Ý định đang chờ xử lý không được kích hoạt nhiều lần nên sử dụng cờ FLAG_ONE_SHOT để tránh bị tấn công phát lại.
Kotlin
val pendingIntent =
PendingIntent.getActivity(
context,
/* requestCode = */ 0,
Intent(intentAction),
PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_ONE_SHOT)
Java
PendingIntent pendingIntent =
PendingIntent.getActivity(
getContext(),
/* requestCode= */ 0,
new Intent(intentAction),
PendingIntent.FLAG_IMMUTABLE | PendingIntent.FLAG_ONE_SHOT);
Tài nguyên
Tài nguyên
Đề xuất cho bạn
Nội dung và mã mẫu trên trang này phải tuân thủ các giấy phép như mô tả trong phần Giấy phép nội dung. Java và OpenJDK là nhãn hiệu hoặc nhãn hiệu đã đăng ký của Oracle và/hoặc đơn vị liên kết của Oracle.
Cập nhật lần gần đây nhất: 2023-12-14 UTC.
[[["Dễ hiểu","easyToUnderstand","thumb-up"],["Giúp tôi giải quyết được vấn đề","solvedMyProblem","thumb-up"],["Khác","otherUp","thumb-up"]],[["Thiếu thông tin tôi cần","missingTheInformationINeed","thumb-down"],["Quá phức tạp/quá nhiều bước","tooComplicatedTooManySteps","thumb-down"],["Đã lỗi thời","outOfDate","thumb-down"],["Vấn đề về bản dịch","translationIssue","thumb-down"],["Vấn đề về mẫu/mã","samplesCodeIssue","thumb-down"],["Khác","otherDown","thumb-down"]],["Cập nhật lần gần đây nhất: 2023-12-14 UTC."],[],[],null,["# Pending intents\n\n\u003cbr /\u003e\n\n**OWASP category:** [MASVS-PLATFORM: Platform Interaction](https://mas.owasp.org/MASVS/09-MASVS-PLATFORM)\n\n\nOverview\n--------\n\nA [`PendingIntent`](/reference/android/app/PendingIntent) is a reference to a token maintained by the system. Application A can pass a PendingIntent to application B in order to allow application B to execute predefined actions on behalf of application A; regardless of whether application A is still alive.\n\nRisk: Mutable Pending Intents\n-----------------------------\n\nA PendingIntent can be mutable, which means that the inner intent that specifies the action can be updated by application B following the logic described in the [`fillIn()`](/reference/android/content/Intent#fillIn(android.content.Intent,%20int)) documentation. In other words, the unfilled fields of a PendingIntent can be modified by a malicious app and allow access to otherwise non-exported components of the vulnerable application.\n\n### Impact\n\nThe impact of this vulnerability varies depending on the implementation of the targeted unexported functionality of the app.\n\n### Mitigations\n\n#### General\n\nMake sure action, component, and package are set to avoid the worst vulnerabilities: \n\n### Kotlin\n\n val intent = Intent(intentAction)\n\n // Or other component setting APIs e.g. setComponent, setClass\n intent.setClassName(packageName, className)\n\n PendingIntent pendingIntent =\n PendingIntent.getActivity(\n context,\n /* requestCode = */ 0,\n intent, /* flags = */ PendingIntent.FLAG_IMMUTABLE\n )\n\n### Java\n\n Intent intent = new Intent(intentAction);\n\n // Or other component setting APIs e.g. setComponent, setClass\n intent.setClassName(packageName, className);\n\n PendingIntent pendingIntent =\n PendingIntent.getActivity(\n getContext(),\n /* requestCode= */ 0,\n intent, /* flags= */ 0);\n\n#### Flag IMMUTABLE\n\nIf your app targets Android 6 (API level 23) or higher, [specify mutability](/guide/components/intents-filters#DeclareMutabilityPendingIntent). For example, this can be done by using [`FLAG_IMMUTABLE`](/reference/android/app/PendingIntent#FLAG_IMMUTABLE) to prevent unfilled fields from being filled in by a malicious application: \n\n### Kotlin\n\n val pendingIntent =\n PendingIntent.getActivity(\n context,\n /* requestCode = */ 0,\n Intent(intentAction),\n PendingIntent.FLAG_IMMUTABLE)\n\n### Java\n\n PendingIntent pendingIntent =\n PendingIntent.getActivity(\n getContext(),\n /* requestCode= */ 0,\n new Intent(intentAction),\n PendingIntent.FLAG_IMMUTABLE);\n\nOn Android 11 (API level 30) and higher, you have to specify which fields to make mutable, which mitigates accidental vulnerabilities of this type.\n\n### Resources\n\n- [Remediation of PendingIntent vulnerability](https://support.google.com/faqs/answer/9267555)\n\n- [Blog post about the vulnerability](https://valsamaras.medium.com/pending-intents-a-pentesters-view-92f305960f03)\n\n*** ** * ** ***\n\nRisk: Replaying Pending Intents\n-------------------------------\n\nA PendingIntent can be replayed unless the [FLAG_ONE_SHOT](/reference/android/app/PendingIntent#FLAG_ONE_SHOT) flag is set. It is important to use FLAG_ONE_SHOT to avoid replay attacks (performing actions that should not be repeatable).\n\n### Impact\n\nThe impact of this vulnerability varies depending on the implementation of the receiving end of the intent. A malicious app exploiting a PendingIntent that was created without setting the FLAG_ONE_SHOT flag could capture and re-use the intent to repeat actions that should only be able to be done once.\n\n### Mitigations\n\nPending Intents not intended to be fired multiple times should use the [FLAG_ONE_SHOT](/reference/android/app/PendingIntent#FLAG_ONE_SHOT) flag to avoid replay attacks. \n\n### Kotlin\n\n val pendingIntent =\n PendingIntent.getActivity(\n context,\n /* requestCode = */ 0,\n Intent(intentAction),\n PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_ONE_SHOT)\n\n### Java\n\n PendingIntent pendingIntent =\n PendingIntent.getActivity(\n getContext(),\n /* requestCode= */ 0,\n new Intent(intentAction),\n PendingIntent.FLAG_IMMUTABLE | PendingIntent.FLAG_ONE_SHOT);\n\n### Resources\n\n- [PendingIntent.FLAG_ONE_SHOT](/reference/android/app/PendingIntent#FLAG_ONE_SHOT)\n\n*** ** * ** ***\n\nResources\n---------\n\n- [PendingIntent documentation](/reference/android/app/PendingIntent)\n\n- [PendingIntent and intent filters](/guide/components/intents-filters#PendingIntent)\n\nRecommended for you\n-------------------\n\n- Note: link text is displayed when JavaScript is off\n- [Intent redirection](/topic/security/risks/intent-redirection)"]]