대기 중인 인텐트

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