Skip to content

MASTG-KNOW-0077: Permissões do App

Em contraste com o Android, onde cada app é executado em seu próprio ID de usuário, o iOS faz com que todos os apps de terceiros sejam executados sob o usuário não privilegiado mobile. Cada app possui um diretório inicial único e é isolado em sandbox, de modo que não possa acessar recursos protegidos do sistema ou arquivos armazenados pelo sistema ou por outros apps. Essas restrições são implementadas por meio de políticas de sandbox (também conhecidas como perfis), que são aplicadas pelo Trusted BSD (MAC) Mandatory Access Control Framework por meio de uma extensão do kernel. O iOS aplica um perfil genérico de sandbox a todos os apps de terceiros chamado container. O acesso a recursos ou dados protegidos (alguns também conhecidos como capacidades do app) é possível, mas é estritamente controlado por meio de permissões especiais conhecidas como entitlements.

Algumas permissões podem ser configuradas pelos desenvolvedores do app (por exemplo, Data Protection ou Keychain Sharing) e entrarão em vigor diretamente após a instalação. No entanto, para outras, o usuário será explicitamente solicitado na primeira vez que o app tentar acessar um recurso protegido, por exemplo:

  • Periféricos Bluetooth
  • Dados de calendário
  • Câmera
  • Contatos
  • Compartilhamento de saúde
  • Atualização de saúde
  • HomeKit
  • Localização
  • Microfone
  • Movimento
  • Música e biblioteca de mídia
  • Fotos
  • Lembretes
  • Siri
  • Reconhecimento de fala
  • Provedor de TV

Embora a Apple insista em proteger a privacidade do usuário e em ser muito clara sobre como solicitar permissões, ainda pode acontecer de um app solicitar muitas delas por motivos não óbvios.

Verificar o uso de algumas permissões, como Câmera, Fotos, Dados de Calendário, Movimento, Contatos ou Reconhecimento de Fala, deve ser bastante direto, pois deve ser óbvio se o app as requer para cumprir suas tarefas. Consideremos os seguintes exemplos em relação à permissão de Fotos, que, se concedida, concede ao app acesso a todas as fotos do usuário no "Camera Roll" (o local padrão em todo o sistema do iOS para armazenar fotos):

  • O típico app de leitura de QR Code obviamente requer a câmera para funcionar, mas também pode estar solicitando a permissão de fotos. Se o armazenamento for explicitamente necessário e dependendo da sensibilidade das fotos tiradas, esses apps podem optar por usar o armazenamento em sandbox do app para evitar que outros apps (com a permissão de fotos) acessem-nas. Consulte o capítulo "Armazenamento de Dados no iOS" para obter mais informações sobre o armazenamento de dados sensíveis.
  • Alguns apps exigem upload de fotos (por exemplo, para fotos de perfil). Versões recentes do iOS introduzem novas APIs, como UIImagePickerController (iOS 11+) e seu substituto moderno PHPickerViewController (iOS 14+). Essas APIs são executadas em um processo separado do seu app e, ao usá-las, o app obtém acesso somente leitura exclusivamente às imagens selecionadas pelo usuário, em vez de todo o "Camera Roll". Isso é considerado uma melhor prática para evitar solicitar permissões desnecessárias.

Verificar outras permissões, como Bluetooth ou Localização, requer uma inspeção mais aprofundada do código-fonte. Elas podem ser necessárias para o funcionamento adequado do app, mas os dados manipulados por essas tarefas podem não estar devidamente protegidos.

Ao coletar ou simplesmente manipular (por exemplo, armazenar em cache) dados sensíveis, um app deve fornecer mecanismos adequados para dar ao usuário controle sobre eles, por exemplo, para poder revogar o acesso ou excluí-los. No entanto, dados sensíveis podem não apenas ser armazenados ou armazenados em cache, mas também enviados pela rede. Em ambos os casos, deve-se garantir que o app siga adequadamente as melhores práticas, que, neste caso, envolvem implementar proteção adequada de dados e segurança de transporte. Mais informações sobre como proteger esse tipo de dados podem ser encontradas no capítulo "APIs de Rede".

Como você pode ver, o uso de capacidades e permissões do app envolve principalmente o manuseio de dados pessoais, sendo, portanto, uma questão de proteger a privacidade do usuário. Consulte os artigos "Protegendo a Privacidade do Usuário" e "Acessando Recursos Protegidos" na Documentação para Desenvolvedores da Apple para obter mais detalhes.

Capacidades do Dispositivo

As capacidades do dispositivo são usadas pela App Store para garantir que apenas dispositivos compatíveis sejam listados e, portanto, tenham permissão para baixar o app. Elas são especificadas no arquivo Info.plist do app sob a chave UIRequiredDeviceCapabilities.

<key>UIRequiredDeviceCapabilities</key>
<array>
    <string>arm64</string>
</array>

Normalmente, você encontrará a capacidade arm64, o que significa que o app é compilado para o conjunto de instruções arm64.

Por exemplo, um app pode ser completamente dependente de NFC para funcionar (por exemplo, um app "NFC Tag Reader"). De acordo com a Referência de Compatibilidade de Dispositivos iOS arquivada, o NFC está disponível apenas a partir do iPhone 7 (e iOS 11). Um desenvolvedor pode querer excluir todos os dispositivos incompatíveis definindo a capacidade de dispositivo nfc.

Em relação aos testes, você pode considerar UIRequiredDeviceCapabilities como uma mera indicação de que o app está usando alguns recursos específicos. Ao contrário dos entitlements relacionados às capacidades do app, as capacidades do dispositivo não conferem qualquer direito ou acesso a recursos protegidos. Etapas adicionais de configuração podem ser necessárias para isso, que são muito específicas para cada capacidade.

Por exemplo, se BLE for um recurso central do app, o Guia de Programação Core Bluetooth da Apple explica as diferentes coisas a serem consideradas:

  • A capacidade de dispositivo bluetooth-le pode ser definida para restringir dispositivos não compatíveis com BLE de baixar seu app.
  • Capacidades do app como bluetooth-peripheral ou bluetooth-central (ambas UIBackgroundModes) devem ser adicionadas se processamento em segundo plano BLE for necessário.

No entanto, isso ainda não é suficiente para o app obter acesso ao periférico Bluetooth; a chave NSBluetoothPeripheralUsageDescription deve ser incluída no arquivo Info.plist, o que significa que o usuário deve ativamente dar permissão. Consulte "Purpose Strings no Arquivo Info.plist" abaixo para obter mais informações.

Entitlements

De acordo com o Guia de Segurança iOS da Apple:

Entitlements são pares de chave-valor que são assinados em um app e permitem autenticação além de fatores de tempo de execução, como o ID de usuário UNIX. Como os entitlements são assinados digitalmente, eles não podem ser alterados. Os entitlements são amplamente usados por apps e daemons do sistema para executar operações privilegiadas específicas que, de outra forma, exigiriam que o processo fosse executado como root. Isso reduz muito o potencial de escalação de privilégios por um app ou daemon do sistema comprometido.

Muitos entitlements podem ser definidos usando a guia "Summary" do editor de destino do Xcode. Outros entitlements exigem a edição de um arquivo de lista de propriedades de entitlements de um destino ou são herdados do perfil de provisionamento iOS usado para executar o app.

Fontes de Entitlements:

  1. Entitlements incorporados em um perfil de provisionamento usado para assinar o app em código, que são compostos por:
  2. Capacidades definidas na guia Capabilities do destino do projeto Xcode, e/ou:
  3. Serviços Habilitados no App ID do app, que são configurados na seção Identifiers do site Certificates, ID's and Profiles.
  4. Outros entitlements injetados pelo serviço de geração de perfis.
  5. Entitlements de um arquivo de entitlements de assinatura de código.

Destinos de Entitlements:

  1. A assinatura do app.
  2. O perfil de provisionamento incorporado do app.

A Documentação para Desenvolvedores da Apple também explica:

  • Durante a assinatura de código, os entitlements correspondentes às Capacidades/Serviços habilitados do app são transferidos para a assinatura do app a partir do perfil de provisionamento que o Xcode escolheu para assinar o app.
  • O perfil de provisionamento é incorporado ao pacote do app durante a compilação (embedded.mobileprovision).
  • Os entitlements da seção "Code Signing Entitlements" na guia "Build Settings" do Xcode são transferidos para a assinatura do app.

Por exemplo, se você quiser definir a capacidade "Default Data Protection", precisaria ir à guia Capabilities no Xcode e habilitar Data Protection. Isso é escrito diretamente pelo Xcode no arquivo <appname>.entitlements como o entitlement com.apple.developer.default-data-protection com valor padrão NSFileProtectionComplete. No IPA, podemos encontrar isso no embedded.mobileprovision como:

<key>Entitlements</key>
<dict>
    ...
    <key>com.apple.developer.default-data-protection</key>
    <string>NSFileProtectionComplete</string>
</dict>

Para outras capacidades, como HealthKit, o usuário deve ser solicitado a dar permissão; portanto, não é suficiente adicionar os entitlements; chaves e strings especiais devem ser adicionadas ao arquivo Info.plist do app.

Purpose Strings no Arquivo Info.plist

As Purpose Strings ou strings de descrição de uso são textos personalizados que são oferecidos aos usuários no alerta de solicitação de permissão do sistema ao solicitar permissão para acessar dados ou recursos protegidos.

Se estiver vinculando no iOS 10 ou posterior, os desenvolvedores são obrigados a incluir Purpose Strings no arquivo Info.plist de seu app. Caso contrário, se o app tentar acessar dados ou recursos protegidos sem ter fornecido a Purpose String correspondente, o acesso falhará e o app pode até mesmo travar.

Para uma visão geral das diferentes chaves Info.plist de Purpose Strings disponíveis, consulte a Tabela 1-2 no Apple App Programming Guide for iOS. Clique nos links fornecidos para ver a descrição completa de cada chave na referência CocoaKeys.

Arquivo de Entitlements de Assinatura de Código

Certas capacidades exigem um arquivo de entitlements de assinatura de código (<appname>.entitlements). Ele é gerado automaticamente pelo Xcode, mas também pode ser editado e/ou estendido manualmente pelo desenvolvedor.

Aqui está um exemplo de arquivo de entitlements do app de código aberto Telegram incluindo o entitlement App Groups (application-groups):

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
...
    <key>com.apple.security.application-groups</key>
    <array>
        <string>group.ph.telegra.Telegraph</string>
    </array>
</dict>
...
</plist>

O entitlement destacado acima não requer nenhuma permissão adicional do usuário. No entanto, é sempre uma boa prática verificar todos os entitlements, pois o app pode solicitar excessivamente o usuário em termos de permissões e, assim, vazar informações.

Conforme documentado na Documentação para Desenvolvedores da Apple, o entitlement App Groups é necessário para compartilhar informações entre diferentes apps por meio de IPC ou um contêiner de arquivo compartilhado, o que significa que os dados podem ser compartilhados diretamente no dispositivo entre os apps. Esse entitlement também é necessário se uma extensão de app precisar compartilhar informações com seu app contêiner.

Dependendo dos dados a serem compartilhados, pode ser mais apropriado compartilhá-los usando outro método, como por meio de um backend onde esses dados poderiam ser potencialmente verificados, evitando adulteração, por exemplo, pelo próprio usuário.