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가 사용 중지되어 있으면 링크 텍스트가 표시됩니다.
- 인텐트 리디렉션