Categoria do OWASP: MASVS-PLATFORM - Interação com plataformas
Visão geral
Uma PendingIntent
é uma referência a um token mantido pelo sistema. O aplicativo A pode transmitir uma PendingIntent para o app B, permitindo que ela execute ações predefinidas em nome do aplicativo original, independente de ele continuar ativo ou não.
Risco: intents pendentes mutáveis
Uma PendingIntent pode ser mutável, ou seja, a intent interna que especifica a ação pode ser atualizada pelo app B seguindo a lógica descrita na documentação de fillIn()
. Em outras palavras, os campos não preenchidos de uma PendingIntent podem ser modificados por um app malicioso e permitir o acesso a componentes não exportados do aplicativo vulnerável.
Impacto
O impacto dessa vulnerabilidade varia de acordo com a implementação da funcionalidade não exportada do app.
Mitigações
Geral
Verifique se a ação, o componente e o pacote estão definidos para evitar as piores vulnerabilidades:
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);
Flag IMMUTABLE
Caso o app seja destinado ao Android 6 (nível 23 da API) ou versões mais recentes, especifique a mutabilidade. Isso pode ser feito, por exemplo, usando FLAG_IMMUTABLE
para impedir que campos em branco sejam preenchidos por um aplicativo malicioso:
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);
No Android 11 (nível 30 da API) e versões mais recentes, é necessário especificar quais campos serão mutáveis. Isso reduz as vulnerabilidades acidentais desse tipo.
Recursos
Postagem do blog sobre a vulnerabilidade (link em inglês)
Risco: repetir intents pendentes
Uma PendingIntent pode ser repetida, a menos que a flag FLAG_ONE_SHOT seja definida. É importante usar FLAG_ONE_SHOT para evitar ataques repetidos, ou seja, realizar ações que não deveriam ser repetidas.
Impacto
O impacto dessa vulnerabilidade varia de acordo com a implementação usada pelo destino final da intent. Um app malicioso que explora uma PendingIntent criada sem definir a flag FLAG_ONE_SHOT pode capturar e reutilizar a intent para repetir ações que só deveriam poder ser feitas uma vez.
Mitigações
As intents pendentes que não devem ser disparadas várias vezes precisam usar a flag FLAG_ONE_SHOT para evitar ataques.
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);
Recursos
Recursos
Recomendados para você
- Observação: o texto do link aparece quando o JavaScript está desativado.
- Redirecionamento de intents