대기 중인 인텐트
컬렉션을 사용해 정리하기
내 환경설정을 기준으로 콘텐츠를 저장하고 분류하세요.
OWASP 카테고리: MASVS-PLATFORM: 플랫폼 상호작용
개요
PendingIntent
는 시스템에서 유지하는 토큰의 참조입니다. 애플리케이션 A는 애플리케이션 A가 아직 살아 있는지와 관계없이 애플리케이션 B가 애플리케이션 A를 대신하여 사전에 정의된 작업을 실행할 수 있도록 애플리케이션 B에 PendingIntent를 전달할 수 있습니다.
위험: 변경 가능한 대기 중인 인텐트
PendingIntent는 변경될 수 있습니다. 즉, 작업을 지정하는 내부 인텐트는 fillIn()
문서에 설명된 로직에 따라 애플리케이션 B에 의해 업데이트될 수 있습니다. 다시 말해, 악성 앱이 PendingIntent의 채워지지 않은 필드를 수정할 수 있으며, 그 외 취약한 애플리케이션의 내보내기하지 않은 구성요소에 액세스하는 것이 허용될 수 있습니다.
영향
이 취약점의 영향은 앱의 타겟팅된 기능 중 내보내기하지 않은 기능의 구현에 따라 달라집니다.
완화 조치
일반
최악의 취약점을 방지하려면 작업, 구성요소, 패키지를 설정해야 합니다.
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);
IMMUTABLE 플래그
앱이 Android 6(API 수준 23) 이상을 타겟팅한다면 변경 가능 여부를 지정해야 합니다. 예를 들어 FLAG_IMMUTABLE
을 사용하면 악성 애플리케이션에서 채워지지 않은 필드를 채우는 것을 방지할 수 있습니다.
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);
Android 11(API 수준 30) 이상에서는 어느 필드를 변경 가능한 필드로 만들지 지정해야 합니다. 그래야 이러한 유형의 취약점이 우발적으로 발생하는 것을 완화할 수 있습니다.
리소스
위험: 대기 중인 인텐트 재생
FLAG_ONE_SHOT 플래그가 설정되지 있지 않으면 PendingIntent가 재생될 수 있습니다. 재생 공격(반복되어서는 안 되는 동작의 실행)을 방지하려면 FLAG_ONE_SHOT을 사용하는 것이 중요합니다.
영향
이 취약점의 영향은 인텐트를 수신하는 지점의 구현에 따라 달라집니다. FLAG_ONE_SHOT 플래그가 설정되지 않은 채로 생성된 PendingIntent를 악용하는 악성 앱이 인텐트를 캡처하고 재사용하여 오직 한 번만 실행될 수 있어야 하는 작업을 반복할 수 있습니다.
완화 조치
재생 공격을 방지하려면 여러 차례 실행되지 않아야 하는 대기 중인 인텐트가 FLAG_ONE_SHOT 플래그를 사용해야 합니다.
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);
리소스
리소스
추천 서비스
- 참고: JavaScript가 사용 중지되어 있으면 링크 텍스트가 표시됩니다.
- 인텐트 리디렉션
이 페이지에 나와 있는 콘텐츠와 코드 샘플에는 콘텐츠 라이선스에서 설명하는 라이선스가 적용됩니다. 자바 및 OpenJDK는 Oracle 및 Oracle 계열사의 상표 또는 등록 상표입니다.
최종 업데이트: 2023-12-08(UTC)
[[["이해하기 쉬움","easyToUnderstand","thumb-up"],["문제가 해결됨","solvedMyProblem","thumb-up"],["기타","otherUp","thumb-up"]],[["필요한 정보가 없음","missingTheInformationINeed","thumb-down"],["너무 복잡함/단계 수가 너무 많음","tooComplicatedTooManySteps","thumb-down"],["오래됨","outOfDate","thumb-down"],["번역 문제","translationIssue","thumb-down"],["샘플/코드 문제","samplesCodeIssue","thumb-down"],["기타","otherDown","thumb-down"]],["최종 업데이트: 2023-12-08(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)"]]