Este documento descreve como os desenvolvedores de apps podem usar os recursos de segurança fornecidos pelo Android para definir as próprias permissões. Ao definir permissões personalizadas, um app pode compartilhar recursos e capabilities com outros apps. Para saber mais sobre permissões, consulte a visão geral de permissões.
Contexto
O Android é um sistema operacional separado por privilégios, em que cada app é executado com uma identidade de sistema distinta (ID do usuário do Linux e ID do grupo). Partes do sistema também são separadas em identidades distintas. Assim, o Linux isola apps uns dos outros e do sistema.
Os apps podem expor a funcionalidade deles a outros aplicativos definindo permissões que outros apps podem solicitar. Eles também podem definir permissões que são disponibilizadas automaticamente para outros apps assinados com o mesmo certificado.
Assinatura de apps
Todos os APKs precisam ser assinados com um certificado cuja chave privada seja mantida pelo desenvolvedor. O certificado não precisa ser assinado por uma autoridade certificadora. É permitido, e normal, que os apps Android usem certificados autoassinados. O objetivo dos certificados no Android é distinguir os autores dos apps. Isso permite que o sistema conceda ou negue acesso dos apps a permissões no nível da assinatura e conceda ou negue solicitação para receber a mesma identidade do Linux de outro app.
Conceder permissões de assinatura após o tempo de fabricação do dispositivo
No Android 12, (nível 31 da API) e versões mais recentes, o
atributo knownCerts
para
permissões no nível da assinatura permite que você consulte as sínteses dos certificados
de assinatura no momento da
declaração.
Declare o atributo knownCerts
e use a flag knownSigner
no atributo protectionLevel
do app
para uma permissão específica no nível da assinatura. O sistema
vai conceder essa permissão a um aplicativo solicitante se qualquer signatário na linhagem
de assinatura dele, incluindo o signatário atual, corresponder a um dos resumos
declarados com a permissão no atributo knownCerts
.
A flag knownSigner
permite que dispositivos e apps concedam permissões de assinatura a
outros aplicativos sem precisar assinar os apps no momento da fabricação
e envio do dispositivo.
IDs de usuário e acesso a arquivos
No momento da instalação, o Android atribui a cada pacote um ID de usuário do Linux diferente. A identidade permanece constante durante a vida útil do pacote nesse dispositivo. Em um dispositivo diferente, o mesmo pacote pode ter um UID diferente; o que importa é que cada pacote tenha um UID distinto em determinado dispositivo.
Como a aplicação da segurança ocorre no nível do processo, o código de dois pacotes normalmente não pode ser executado no mesmo processo, porque eles precisam ser executados como usuários do Linux diferentes.
Todos os dados armazenados por um app recebem o ID do usuário desse app e normalmente não podem ser acessados por outros pacotes.
Para saber mais sobre o modelo de segurança do Android, consulte Visão geral de segurança do Android.
Definir e aplicar permissões
Para aplicar suas próprias permissões, primeiro é necessário declará-las no
AndroidManifest.xml
usando um ou mais elementos
<permission>
.
Convenção de nomenclatura
O sistema não permite que vários pacotes declarem uma permissão com o mesmo nome, a menos que todos os pacotes sejam assinados com o mesmo certificado. Se um pacote declarar uma permissão, o sistema também não vai permitir que o usuário instale outros pacotes com o mesmo nome de permissão, a menos que eles sejam assinados com o mesmo certificado do primeiro.
Recomendamos adicionar o nome do pacote dos apps como prefixo nas permissões, usando
a nomeação no estilo de domínio inverso, seguido por .permission.
e uma descrição da capacidade que a permissão representa com
letras maiúsculas em SNAKE_CASE. Por exemplo:
com.example.myapp.permission.ENGAGE_HYPERSPACE
.
Essa recomendação evita conflitos na nomenclatura e ajuda a identificar com clareza o proprietário e a intenção de uma permissão personalizada.
Exemplo
Por exemplo, um app que precise controlar quais outros aplicativos podem iniciar uma das atividades pode declarar uma permissão para essa operação desta forma:
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.myapp" > <permission android:name="com.example.myapp.permission.DEADLY_ACTIVITY" android:label="@string/permlab_deadlyActivity" android:description="@string/permdesc_deadlyActivity" android:permissionGroup="android.permission-group.COST_MONEY" android:protectionLevel="dangerous" /> ... </manifest>
O atributo
protectionLevel
é obrigatório e relata ao sistema como o
usuário precisa ser informado sobre apps que exigem a permissão ou que podem
manter a permissão, conforme descrito na documentação vinculada.
O atributo android:permissionGroup
é opcional e usado apenas para ajudar o sistema a mostrar permissões
para o usuário. Na maioria dos casos, você define um grupo de sistema
padrão (listado em android.Manifest.permission_group
),
mas também pode definir seu próprio grupo, como descrito na próxima seção.
Recomendamos usar um grupo já criado, porque isso simplifica a
interface de permissões mostrada ao usuário.
Você precisa fornecer um rótulo e uma descrição para a
permissão. Eles são recursos de string mostrados ao usuário quando
aparece uma lista de permissões
(android:label
)
ou detalhes sobre uma única permissão
(android:description
).
O rótulo é curto: algumas palavras que descrevem a
funcionalidade principal que a permissão está protegendo. A descrição contém
algumas frases descrevendo o que pode ser feito por apps com a permissão. Nossa
convenção é uma descrição de duas frases, em que a primeira descreve
a permissão e a segunda avisa o usuário sobre o que
poderá dar errado se um app receber a permissão.
Confira um exemplo de rótulo e descrição para a
permissão
CALL_PHONE
:
<string name="permlab_callPhone">directly call phone numbers</string> <string name="permdesc_callPhone">Allows the app to call non-emergency phone numbers without your intervention. Malicious apps may cause unexpected calls on your phone bill.</string>
Criar um grupo de permissões
Como mostrado na seção anterior, você pode usar o
atributo android:permissionGroup
para ajudar o sistema a descrever
as permissões para o usuário. Na maioria dos casos, você define um grupo de sistema
padrão (listado em
android.Manifest.permission_group
),
mas também pode definir seu próprio grupo com
<permission-group>
.
O elemento <permission-group>
define um rótulo para um conjunto
de permissões, tanto aquelas declaradas no manifesto com
elementos <permission>
quanto aquelas declaradas em outro lugar. Isso afeta apenas a forma como as permissões são
agrupadas quando apresentadas ao usuário. O
elemento
<permission-group>
não especifica as permissões que pertencem ao grupo, mas
fornece um nome ao grupo.
Você pode colocar uma permissão no grupo atribuindo o nome do grupo ao atributo
permissionGroup
do
elemento
<permission>
.
O elemento <permission-tree>
declara um namespace para um grupo de permissões que são definidas no código.
Recomendações para permissões personalizadas
Você pode definir permissões personalizadas para seus apps e solicitar permissões personalizadas
de outros aplicativos definindo elementos <uses-permission>
.
No entanto, avalie com atenção se é necessário fazer isso.
- Se você estiver projetando um pacote de apps que expõem a funcionalidade um ao outro, tente projetar os apps de forma que cada permissão seja definida apenas uma vez. Faça isso se todos os apps não estiverem assinados com o mesmo certificado. Mesmo que os apps sejam assinados com o mesmo certificado, é uma prática recomendada definir cada permissão apenas uma vez.
- Se a funcionalidade só estiver disponível para apps assinados com a mesma assinatura do app de fornecimento, talvez seja possível evitar a definição de permissões personalizadas usando verificações de assinatura. Quando um dos seus apps fizer uma solicitação de outro app, o segundo app poderá verificar se os dois apps estão assinados com o mesmo certificado antes de obedecer à solicitação.
Se uma permissão personalizada for necessária, considere se apenas os apps assinados pelo mesmo desenvolvedor que o aplicativo que executa a verificação de permissões precisam acessá-la, como ao implementar comunicações seguras entre processos entre dois aplicativos do mesmo desenvolvedor. Nesse caso, recomendamos o uso de permissões de assinatura. As permissões de assinatura são transparentes para o usuário e evitam permissões confirmadas por ele, o que pode ser confuso.
Continue lendo sobre:
<uses-permission>
- Referência da API para a tag de manifesto que declara as permissões necessárias do sistema do seu app.
Talvez você também tenha interesse em:
- Visão geral de segurança do Android
- Uma discussão detalhada sobre o modelo de segurança da plataforma Android.