A plataforma Android aproveita a proteção baseada no usuário do Linux para identificar e isolar recursos do aplicativo. Isso isola os aplicativos uns dos outros e protege os aplicativos e o sistema contra aplicativos maliciosos. Para fazer isso, o Android atribui um ID de usuário exclusivo (UID) a cada aplicativo Android e o executa em seu próprio processo.
O Android usa o UID para configurar um Application Sandbox em nível de kernel. O kernel reforça a segurança entre os aplicativos e o sistema no nível do processo por meio de recursos padrão do Linux, como IDs de usuários e grupos atribuídos aos aplicativos. Por padrão, os aplicativos não podem interagir entre si e têm acesso limitado ao sistema operacional. Se o aplicativo A tentar fazer algo malicioso, como ler os dados do aplicativo B ou discar o telefone sem permissão, ele será impedido de fazer isso porque não possui os privilégios de usuário padrão apropriados. O sandbox é simples, auditável e baseado na separação de processos e permissões de arquivo do usuário, no estilo UNIX, de décadas atrás.
Como o Application Sandbox está no kernel, esse modelo de segurança se estende ao código nativo e aos aplicativos do sistema operacional. Todos os softwares acima do kernel, como bibliotecas de sistema operacional, estrutura de aplicativos, tempo de execução de aplicativos e todos os aplicativos, são executados no Application Sandbox. Em algumas plataformas, os desenvolvedores estão restritos a uma estrutura de desenvolvimento, conjunto de APIs ou linguagem específica. No Android, não há restrições sobre como um aplicativo pode ser escrito, o que é necessário para reforçar a segurança; nesse aspecto, o código nativo é tão protegido quanto o código interpretado.
Proteções
Geralmente, para sair do Application Sandbox em um dispositivo configurado corretamente, é necessário comprometer a segurança do kernel Linux. No entanto, semelhante a outros recursos de segurança, as proteções individuais que aplicam a sandbox do aplicativo não são invulneráveis, portanto, a defesa profunda é importante para evitar que vulnerabilidades únicas levem ao comprometimento do sistema operacional ou de outros aplicativos.
O Android depende de uma série de proteções para impor a sandbox do aplicativo. Essas imposições foram introduzidas ao longo do tempo e fortaleceram significativamente a sandbox original de controle de acesso discricionário (DAC) baseada em UID. As versões anteriores do Android incluíam as seguintes proteções:
- No Android 5.0, o SELinux forneceu separação obrigatória de controle de acesso (MAC) entre o sistema e os aplicativos. No entanto, todos os aplicativos de terceiros foram executados no mesmo contexto SELinux, portanto, o isolamento entre aplicativos foi aplicado principalmente pelo UID DAC.
- No Android 6.0, o sandbox SELinux foi estendido para isolar aplicativos além do limite por usuário físico. Além disso, o Android também definiu padrões mais seguros para dados de aplicativos: para aplicativos com
targetSdkVersion >= 24
, as permissões DAC padrão no diretório inicial de um aplicativo foram alteradas de 751 para 700. Isso forneceu um padrão mais seguro para dados de aplicativos privados (embora os aplicativos possam substituir esses padrões) . - No Android 8.0, todos os aplicativos foram configurados para serem executados com um filtro
seccomp-bpf
que limitava as syscalls que os aplicativos podiam usar, fortalecendo assim o limite aplicativo/kernel. - No Android 9, todos os aplicativos sem privilégios com
targetSdkVersion >= 28
devem ser executados em sandboxes SELinux individuais, fornecendo MAC por aplicativo. Essa proteção melhora a separação de aplicativos, evita a substituição de padrões seguros e (mais significativamente) impede que os aplicativos tornem seus dados acessíveis. - No Android 10, os aplicativos têm uma visão bruta limitada do sistema de arquivos, sem acesso direto a caminhos como /sdcard/DCIM. No entanto, os aplicativos mantêm acesso bruto total aos caminhos específicos do pacote, conforme retornado por quaisquer métodos aplicáveis, como Context.getExternalFilesDir() .
Diretrizes para compartilhar arquivos
Definir os dados do aplicativo como acessíveis mundialmente é uma prática de segurança inadequada. O acesso é concedido a todos e não é possível limitar o acesso apenas ao(s) destinatário(s) pretendido(s). Essa prática levou a vazamentos de divulgação de informações e confundiu vulnerabilidades de deputados, e é um alvo favorito para malware que visa aplicativos com dados confidenciais (como clientes de e-mail). No Android 9 e versões posteriores, o compartilhamento de arquivos dessa forma é explicitamente proibido para aplicativos com targetSdkVersion>=28
.
Em vez de tornar os dados do aplicativo acessíveis ao mundo, use as seguintes diretrizes ao compartilhar arquivos:
- Se seu aplicativo precisar compartilhar arquivos com outro aplicativo, use um provedor de conteúdo . Os provedores de conteúdo compartilham dados com a granularidade adequada e sem as muitas desvantagens das permissões UNIX acessíveis mundialmente (para obter detalhes, consulte Princípios básicos do provedor de conteúdo ).
- Se seu aplicativo tiver arquivos que realmente deveriam ser acessíveis ao mundo (como fotos), eles deverão ser específicos da mídia (somente fotos, vídeos e arquivos de áudio) e armazenados usando a classe MediaStore . (Para obter mais detalhes sobre como adicionar um item de mídia, consulte Acessar arquivos de mídia do armazenamento compartilhado .)
A permissão de tempo de execução do Storage controla o acesso a coleções fortemente tipadas por meio do MediaStore . Para acessar arquivos com digitação fraca, como PDFs e a classe MediaStore.Downloads , os aplicativos devem usar intenções como a intenção ACTION_OPEN_DOCUMENT .
Para ativar o comportamento do Android 10, use o atributo de manifesto requestLegacyExternalStorage
e siga as práticas recomendadas para permissões de aplicativos .
- O valor padrão do sinalizador de manifesto é
true
para aplicativos direcionados ao Android 9 (e versões anteriores). - O valor padrão é false para aplicativos direcionados ao Android 10. Para desativar temporariamente a visualização de armazenamento filtrado em aplicativos direcionados ao Android 10, defina o valor do sinalizador de manifesto como
true
. - Usando permissões restritas, o instalador coloca na lista de permissões os aplicativos permitidos para armazenamento fora da área restrita. Os aplicativos que não estão na lista de permissões são colocados em sandbox.