Categoria do OWASP: MASVS-PLATFORM - Interação com plataformas
Visão geral
Uma permissão do Android é um identificador de string declarado no manifesto do app para solicitar acesso a dados ou ações restritas, aplicadas no ambiente de execução pelo framework do Android.
Os níveis de permissão do Android indicam o risco potencial associado à permissão:
- Normal: permissões de baixo risco, concedidas automaticamente no momento da instalação
- Perigosas: permissões de alto risco que podem permitir o acesso a dados sensíveis do usuário, exigindo aprovação explícita do usuário no momento da execução.
- Assinatura: concedida apenas a apps assinados com o mesmo certificado do app que declara a permissão, geralmente usada para apps do sistema ou interações entre apps do mesmo desenvolvedor.
As vulnerabilidades relacionadas a controles de acesso baseados em permissões ocorrem quando um componente de um app (como atividade, receptor, provedor de conteúdo ou serviço) atende a todos os seguintes critérios:
- O componente não está associado a nenhum
android:permissionnoManifest. - O componente realiza uma tarefa sensível para a qual existe uma permissão que o usuário já aprovou.
- O componente é exportado.
- O componente não realiza verificações manuais de permissão (manifesto ou nível de código).
Quando isso acontece, um app malicioso pode realizar ações sensíveis abusando dos privilégios do componente vulnerável, transferindo os privilégios do app vulnerável para o app malicioso.
Impacto
A exportação de componentes vulneráveis pode ser usada para acessar recursos sensíveis ou realizar ações confidenciais. O impacto desse comportamento indesejado depende do contexto do componente vulnerável e dos privilégios dele.
Mitigações
Exigir permissões para tarefas sensíveis
Ao exportar um componente com permissões sensíveis, exija as mesmas permissões para qualquer solicitação recebida. O ambiente de desenvolvimento integrado do Android Studio tem verificações do lint para receivers e services para identificar essa vulnerabilidade e recomendar a exigência das permissões adequadas.
Os desenvolvedores podem exigir permissões para solicitações recebidas declarando-as no arquivo Manifest ou no nível do código ao implementar o serviço, como nos exemplos a seguir.
XML
<manifest ...>
<uses-permission android:name="android.permission.READ_CONTACTS" />
<application ...>
<service android:name=".MyExportService"
android:exported="true"
android:permission="android.permission.READ_CONTACTS" />
</application>
</manifest>
Kotlin
class MyExportService : Service() {
private val binder = MyExportBinder()
override fun onBind(intent: Intent): IBinder? {
// Enforce calling app has the required permission
enforceCallingPermission(Manifest.permission.READ_CONTACTS, "Calling app doesn't have READ_CONTACTS permission.")
// Permission is enforced, proceed with export logic
return binder
}
// Inner class for your Binder implementation
private inner class MyExportBinder : Binder() {
// Permission is enforced, proceed with export logic
}
}
Java
public class MyExportService extends Service {
@Override
public IBinder onBind(Intent intent) {
// Enforce calling app has the required permission
enforceCallingPermission(Manifest.permission.READ_CONTACTS, "Calling app doesn't have READ_CONTACTS permission.");
return binder;
}
// Inner class for your Binder implementation
private class MyExportBinder extends Binder {
// Permission is enforced, proceed with export logic
}
}
Não exportar o componente
Evite exportar componentes com acesso a recursos sensíveis, a menos que seja absolutamente necessário. Para isso, defina android:exported no arquivo
Manifest como false para seu componente. A partir do nível 31 da API e além, esse atributo é definido como false por padrão.
XML
<activity
android:name=".MyActivity"
android:exported="false"/>
Aplicar permissões baseadas em assinatura
Ao compartilhar dados entre dois apps que você controla ou possui, use permissões baseadas em assinatura. Essas permissões não exigem confirmação do usuário. Em vez disso, elas verificam se os apps que acessam os dados são assinados com a mesma chave de assinatura. Essa configuração oferece uma experiência do usuário mais simples e segura. Se você declarar permissões personalizadas, considere as diretrizes de segurança correspondentes.
XML
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.myapp">
<permission android:name="my_custom_permission_name"
android:protectionLevel="signature" />
Endpoints de tarefa única
Implemente o app seguindo o princípio de design Separação de interesses. Cada endpoint só pode realizar um pequeno conjunto de tarefas específicas com privilégios específicos. Essa prática de design também permite que o desenvolvedor aplique permissões granulares a cada endpoint. Por exemplo, evite criar um endpoint único que atenda à agenda e aos contatos.
Recursos
- Acesso do Android a componentes protegidos por apps no blog Oversecured (em inglês)
- Práticas recomendadas para provedores de conteúdo
- Permissões de tempo de execução (perigosas)
- Princípio de design de separação de conceitos
- Documentação sobre permissões do Android
- Dicas de segurança para broadcast receivers do Android
- Dicas de segurança dos serviços do Android
- O conjunto padrão exportado do Android 12 (API 31) foi definido como "false"
- Verificação de lint: Exported PreferenceActivity não deve ser exportado
- Verificação de lint: o receptor exportado não exige permissão
- Verificação de lint: o serviço exportado não exige permissão