TIL - 18
# PendingIntent.FLAG_IMMUTABLE vs PendingIntent.FLAG_MUTABLE
API 31 이상을 타겟팅하고 PendingIntent를 사용할 때 “FLAG_IMMUTABLE” 또는 “FLAG_MUTABLE” Flag를 추가하지 않으면 에러가 발생합니다. 해당 Flag는 어떤 역할을 하며 왜 강제로 사용하게 변경되었을까요?
## PendingIntent란?
해당 Flag를 알아가기에 앞서 PendingIntent가 어떤 것인지에 대해 먼저 알아갈 필요가 있습니다.
안드로이드에서 “Intent” 는 메시징 객체로, 다른 앱 구성 요소로 부터 작업을 요청하는데 사용할 수 있으며, 액티비티 시작, 서비스 시작, 브로드캐스트 전달 등을 할 수 있습니다.
여기서 “Pending(있을 때 까지, …을 기다리는 동안)”이라는 이름이 붙여져 있습니다.이름을 통해 유추할 수 있듯이, 애플리케이션 A가 살아 있는지와 관계없이 애플리케이션 B가 애플리케이션 A를 대신하여 사전에 정의된 작업을 실행할 수 있도록 애플리케이션 B에 PendingIntent를 전달하여 사용할 수 있습니다. 즉, 다른 애플리케이션의 권한을 허가하여 가지고 있는 Intent를 마치 본인 앱의 프로세스에서 실행하는 것처럼 사용하게 하는 것입니다.
대표적인 예로는 알림을 예로 들을 수 있습니다. 알림은 애플리케이션과 다르게 별도의 프로세스로 동작하고 있습니다. 알림이 오고 알림을 누르게 되면 액티비티가 실행되게 하려면 Intent가 아닌 PendingIntent를 통해서 액티비티를 열 수 있도록 해줘야 합니다.
## 보안상 이슈
“PendingIntent”가 애플리케이션의 권한을 다른 애플리케이션에 양도할 수 있다는 사실을 알 수 있었습니다. 그러면 그만큼 보안 측면인 이슈도 생기기 마련입니다. 아래와 같은 시나리오가 있다고 가정해 보겠습니다.
1. 파일 다운로더 앱 A에서 연락처 접근 권한을 가지고 있으며, 악성 앱 B에서는 연락처 권한이 없습니다.
2. 악성 앱 B에 다른 앱 알림을 읽을 수 있는 권한이 있습니다. (BIND_NOTIFICATION_LISTENER_SERVICE)
3. 앱 A에서 파일을 다운로드 시 Notification에 PendingIntent를 통해서 앱 A의 액티비티를 실행할 수 있도록 설정해 줍니다.
여기서 어떠한 문제가 생길까요? 문제가 생기는 시나리오는 아래와 같습니다.
1. 앱 A에서 다운로드 관련 알림이 떴을 때 악성 앱 B에서는 알림을 읽을 수 있는 권한을 통해서 PendingIntent를 가져올 수 있습니다.
2. 앱 A의 PendingIntent에 연락처 권한을 통해 연락처 정보를 가져와 악성 앱 B에 전달하는 Intent를 PendingIntent에 세팅하여 send 합니다.
3. 악성 앱 B에서는 연락처 권한이 없지만 앱 A의 권한을 통해서 연락처 정보를 가져올 수 있습니다.
이러한 이유가 발생한 이유가 PendingIntent의 Intent를 변경할 수 있어서 일어난 이슈입니다. 이를 예방하고자 “FLAG_IMMUTABLE" 또는 “FLAG_MUTABLE" flag를 강제로 사용하게 만듭니다.
## 방지 방법
### FLAG_IMMUTABLE
Immutable “변경할 수 없는”, “불변의” 라는 뜻을 가지고 있습니다. 즉 다른 앱에서 Intent를 변경하지 못하게 막아버리는 flag라고 할 수 있습니다. 이를 통해서 악성 앱이 악용하는 것을 방지할 수 있습니다.
```kotlin
val pendingIntent =
PendingIntent.getActivity(
context,
/* requestCode = */ 0,
Intent(intentAction),
PendingIntent.FLAG_IMMUTABLE)
```
### FLAG_MUTABLE
안정성을 위해서는 “FLAG_IMMUTABLE”을 사용하면 될 것 같은데, “FLAG_MUTABLE”는 어떤 경우에 사용하는 걸까요? 공식 문서상 해당 Flag는 알림을 통해서 답장할 수 있는 기능 또는 도움말 풍선과 같이 기능적으로 이미 존재하는 인텐트를 수정해야 하는 로직에서만 적용할 것을 권고합니다.
알림 답장
https://developer.android.com/develop/ui/views/notifications#Heads-up
도움말 풍선
https://developer.android.com/guide/topics/ui/bubbles?hl=ko
## 참고
- https://support.google.com/faqs/answer/9267555?hl=ko
- https://valsamaras.medium.com/pending-intents-a-pentesters-view-92f305960f03