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 restritos, aplicados no ambiente de execução pelo framework do Android.
Os níveis de permissão do Android indicam o possível risco 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 a 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, normalmente usada para apps do sistema ou interações entre apps do mesmo desenvolvedor.
Vulnerabilidades relacionadas a controles de acesso baseados em permissões ocorrem quando um componente de app (como atividade, broadcast receiver, provedor de conteúdo ou serviço) atende a todos os seguintes critérios:
- O componente não está associado a nenhuma
android:permission
noManifest
. - O componente executa 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 (no nível do manifesto ou do código).
Quando isso acontece, um app malicioso pode realizar ações sensíveis abusando dos privilégios do componente vulnerável, fazendo proxy dos 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 sensíveis. 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 essas mesmas permissões para qualquer solicitação recebida. O ambiente de desenvolvimento integrado do Android Studio tem verificações de lint para recebedores e serviços para detectar 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 fazer isso, defina android:exported
no
arquivo Manifest
como false
para o componente. A partir do nível 31 da API e
mais recentes, 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 a 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 seu app seguindo o princípio de design Separação de preocupações. Cada endpoint precisa executar apenas um pequeno conjunto de tarefas específicas com privilégios específicos. Essa boa prática de design também permite que o desenvolvedor aplique permissões detalhadas para cada endpoint. Por exemplo, evite criar um endpoint único que atenda a agenda e aos contatos.
Recursos
- Acesso do Android a componentes protegidos de apps do blog Oversecured (em inglês)
- Práticas recomendadas para provedores de conteúdo
- Permissões de execução (perigosas)
- Princípio de design de separação de conceitos
- Documentação de permissões do Android
- Dicas de segurança para broadcast receivers do Android
- Dicas de segurança dos Serviços do Android
- O Android 12 (API 31) exportado foi definido como "false"
- Verificação de lint: a PreferenceActivity exportada não pode ser exportada
- 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