Categoria do OWASP: MASVS-PLATFORM - Interação com plataformas
Visão geral
Os apps e o sistema Android podem usar transmissões como um sistema de mensagens para notificar outros apps sobre eventos em que possam ter interesse. As transmissões fixas são um tipo especial. Nelas, os objetos de intent enviados permanecem no cache após a conclusão da transmissão. O sistema pode retransmitir intents fixas para receptores que foram registrados. Infelizmente, a API de transmissões fixas apresentava diversas limitações relacionadas à segurança e, por isso, foi descontinuada no Android 5.0 (API de nível 21).
Qualquer pessoa pode acessar transmissões fixas
As transmissões fixas não podem ser restritas a receptores que têm determinadas permissões. Portanto, elas não são adequadas para transmitir informações sensíveis. Você pode até pensar que especificar o nome do pacote do aplicativo na Intent
de transmissão limita o conjunto de BroadcastReceivers
:
Kotlin
val intent = Intent("com.example.NOTIFY").apply {
setPackage("com.example.myapp")
}
applicationContext.sendBroadcast(intent)
Java
Intent intent = new Intent("com.example.NOTIFY");
intent.setPackage("com.example.myapp");
getApplicationContext().sendBroadcast(intent);
No exemplo, apenas os receptores no pacote com.example.myapp
recebem a intent quando a transmissão é enviada. Porém, o filtro de nome de pacote não é aplicado quando a intent é retransmitida do cache fixo. Ao registrar um receptor usando o método registerReceiver()
, todas as intents no cache fixo que correspondem ao filtro especificado são retransmitidas para o receptor, independentemente do pacote em que o receptor reside.
Qualquer pessoa pode enviar transmissões fixas
Para enviar transmissões fixas, um app só precisa ter a permissão android.permission.BROADCAST_STICKY
, que é concedida automaticamente quando ele é instalado. Portanto, os invasores podem enviar qualquer intent a qualquer receptor, possivelmente ganhando acesso não autorizado a outro app. Os broadcast receivers podem restringir os remetentes àqueles que têm uma determinada permissão. Ao fazer isso, entretanto, o receptor não pode receber transmissões do cache fixo, porque elas não são enviadas no contexto da identidade de um app e não são transmitidas com permissões.
Qualquer pessoa pode modificar transmissões fixas
Quando uma intent faz parte de uma transmissão fixa, ela substitui todas as instâncias anteriores que tenham a mesma ação, dados, tipo, identificador, classe e categorias no cache fixo. Portanto, um invasor pode substituir os dados extras em uma intent fixa de um app legítimo, que pode ser retransmitida para outros receptores.
As transmissões enviadas usando o método sendStickyOrderedBroadcast()
são entregues a um receptor por vez, permitindo que aqueles com maior prioridade consumam a transmissão antes que ela seja entregue aos receptores com menor prioridade. À medida que cada receptor é executado, ele pode propagar um resultado para o próximo receptor, por exemplo, chamando setResultData()
, ou pode cancelar a transmissão, impedindo que os receptores subsequentes a recebam. Um invasor que recebe transmissões ordenadas fixas de um app legítimo pode criar um receptor de alta prioridade para adulterar os dados do resultado da transmissão ou fazer o descarte completo dela.
Impacto
O impacto varia de acordo com a forma como as transmissões fixas são usadas e quais dados são transmitidos aos broadcast receivers. De modo geral, o uso de transmissões fixas pode levar a exposição de dados sensíveis, adulteração de dados, acesso não autorizado para realizar um comportamento em outro app e negação de serviço.
Mitigações
Transmissões fixas não devem ser usadas. O padrão recomendado é usar transmissões não fixas com outro mecanismo, como um banco de dados local, para recuperar o valor atual sempre que desejado.
Os desenvolvedores conseguem controlar quem pode receber transmissões não fixas usando permissões ou definindo o nome do pacote do app na intent. Além disso, se uma transmissão não precisar ser enviada para componentes fora de um app, use o LiveData
, que implementa
o padrão do observador (link em inglês).
Acesse a página Visão geral de transmissões para aprender a protegê-las.