Skip to content

MASTG-TECH-0137: Análise de Arquivos PrivacyInfo.xcprivacy

Uma vez que você tenha obtido um manifesto de privacidade conforme indicado em Recuperação de Arquivos PrivacyInfo.xcprivacy, você pode prosseguir com a análise.

Vamos usar o arquivo SocialApp.app/PrivacyInfo.xcprivacy como exemplo.

SocialApp.app/PrivacyInfo.xcprivacy
<?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>NSPrivacyAccessedAPITypes</key>
        <array>
                <dict>
                        <key>NSPrivacyAccessedAPIType</key>
                        <string>NSPrivacyAccessedAPICategoryUserDefaults</string>
                        <key>NSPrivacyAccessedAPITypeReasons</key>
                        <array>
                                <string>CA92.1</string>
                                <string>1C8F.1</string>
                                <string>C56D.1</string>
                        </array>
                </dict>
                <dict>
                        <key>NSPrivacyAccessedAPIType</key>
                        <string>NSPrivacyAccessedAPICategoryActiveKeyboards</string>
                        <key>NSPrivacyAccessedAPITypeReasons</key>
                        <array>
                                <string>54BD.1</string>
                        </array>
                </dict>
        </array>
        <key>NSPrivacyCollectedDataTypes</key>
        <array>
                <dict>
                        <key>NSPrivacyCollectedDataType</key>
                        <string>NSPrivacyCollectedDataTypeName</string>
                        <key>NSPrivacyCollectedDataTypeLinked</key>
                        <true/>
                        <key>NSPrivacyCollectedDataTypePurposes</key>
                        <array>
                                <string>NSPrivacyCollectedDataTypePurposeAppFunctionality</string>
                                <string>NSPrivacyCollectedDataTypePurposeOther</string>
                        </array>
                        <key>NSPrivacyCollectedDataTypeTracking</key>
                        <false/>
                </dict>
                <dict>
                        <key>NSPrivacyCollectedDataType</key>
                        <string>NSPrivacyCollectedDataTypeOtherDiagnosticData</string>
                        <key>NSPrivacyCollectedDataTypeLinked</key>
                        <true/>
                        <key>NSPrivacyCollectedDataTypePurposes</key>
                        <array>
                                <string>NSPrivacyCollectedDataTypePurposeAnalytics</string>
                                <string>NSPrivacyCollectedDataTypePurposeAppFunctionality</string>
                                <string>NSPrivacyCollectedDataTypePurposeOther</string>
                        </array>
                        <key>NSPrivacyCollectedDataTypeTracking</key>
                        <false/>
                </dict>
        </array>
        <key>NSPrivacyTracking</key>
        <true/>
        <key>NSPrivacyTrackingDomains</key>
        <array>
                <string>trk-v2.socialapp.com</string>
                <string>trk-v2.socialapp.us</string>
                <string>trk-v2.socialapp.eu</string>
        </array>
</dict>
</plist>

Este arquivo PrivacyInfo.xcprivacy contém:

  • NSPrivacyAccessedAPITypes: Lista os tipos de APIs acessadas pelo app junto com suas razões de acesso. Neste caso:
    • NSPrivacyAccessedAPICategoryUserDefaults: UserDefaults acessado pelas razões CA92.1, 1C8F.1, C56D.1.
    • NSPrivacyAccessedAPICategoryActiveKeyboards: interação com teclados ativos acessada pela razão 54BD.1.
  • NSPrivacyCollectedDataTypes: Lista os tipos de dados coletados pelo app e as finalidades específicas. Também indica se os dados coletados estão vinculados à identidade do usuário (NSPrivacyCollectedDataTypeLinked) e se são usados para fins de rastreamento (NSPrivacyCollectedDataTypeTracking). Neste caso:
    • NSPrivacyCollectedDataTypeName: coleta o nome do usuário com finalidades incluindo "Funcionalidade do App" e "Outros" (vinculado à identidade do usuário, mas não usado para rastreamento).
    • NSPrivacyCollectedDataTypeOtherDiagnosticData: coleta outros dados de diagnóstico para finalidades incluindo "Análises", "Funcionalidade do App" e "Outros" (vinculado à identidade do usuário, mas não usado para rastreamento).
  • NSPrivacyTracking: Indica que o SocialApp usa dados para rastreamento conforme definido no framework de Transparência de Rastreamento de Apps.
  • NSPrivacyTrackingDomains: Lista os domínios usados para fins de rastreamento, que neste caso inclui vários domínios relacionados ao SocialApp.

Você pode usar várias ferramentas e parsers para ler e analisar esses arquivos programaticamente.

Usando jq

Se você converter o arquivo PrivacyInfo.xcprivacy para formato JSON conforme descrito em Converter Arquivos Plist para JSON, pode usar jq para fazer consultas.

Por exemplo, para extrair todos os NSPrivacyAccessedAPITypeReasons para cada NSPrivacyAccessedAPIType:

cat SocialApp.app/PrivacyInfo.json | jq '.NSPrivacyAccessedAPITypes[] | {api: .NSPrivacyAccessedAPIType, reasons: .NSPrivacyAccessedAPITypeReasons}'

Que produz (truncado para legibilidade):

{
  "api": "NSPrivacyAccessedAPICategoryUserDefaults",
  "reasons": [
    "CA92.1",
    "1C8F.1",
    "C56D.1"
  ]
}
{
  "api": "NSPrivacyAccessedAPICategorySystemBootTime",
  "reasons": [
    "35F9.1"
  ]
}
...

Os benefícios incluem saída legível, ferramentas JSON padrão e sintaxe de seleção concisa. As ressalvas são que datas e blobs de dados brutos se tornam strings, a precisão numérica pode mudar, e comentários e ordenação de chaves são perdidos. Considere o módulo plistlib do Python se precisar preservar tipos específicos de plist.

Usando plistlib

Use o módulo integrado plistlib do Python para ler e manipular arquivos plist, incluindo PrivacyInfo.xcprivacy.

Por exemplo, para extrair os NSPrivacyAccessedAPITypeReasons para cada NSPrivacyAccessedAPIType:

import plistlib
import json

# carrega o plist .xcprivacy
with open('SocialApp.app/PrivacyInfo.xcprivacy', 'rb') as fp:
    data = plistlib.load(fp)

# extrai e imprime cada API e suas razões em JSON
for item in data.get('NSPrivacyAccessedAPITypes', []):
    api = item.get('NSPrivacyAccessedAPIType')
    reasons = item.get('NSPrivacyAccessedAPITypeReasons')
    print(json.dumps({'api': api, 'reasons': reasons}, ensure_ascii=False))

A saída é (truncada para legibilidade):

{"api": "NSPrivacyAccessedAPICategoryUserDefaults", "reasons": ["CA92.1", "1C8F.1", "C56D.1"]}
{"api": "NSPrivacyAccessedAPICategorySystemBootTime", "reasons": ["35F9.1"]}
...

Usando PlistBuddy

Use PlistBuddy para ler e manipular arquivos plist diretamente sem convertê-los para JSON, incluindo PrivacyInfo.xcprivacy.

Por exemplo, você pode ler NSPrivacyAccessedAPITypes usando o seguinte comando:

/usr/libexec/PlistBuddy -c "Print NSPrivacyAccessedAPITypes" ./SocialApp.app/PrivacyInfo.xcprivacy
Array {
    Dict {
        NSPrivacyAccessedAPIType = NSPrivacyAccessedAPICategoryUserDefaults
        NSPrivacyAccessedAPITypeReasons = Array {
            CA92.1
            1C8F.1
            C56D.1
        }
    }
    ...
}

Você pode aprofundar-se no arquivo para extrair informações mais específicas. Por exemplo, pode obter os NSPrivacyAccessedAPITypeReasons do primeiro elemento de NSPrivacyAccessedAPITypes (índice 0) desta forma:

/usr/libexec/PlistBuddy -c "Print NSPrivacyAccessedAPITypes:0:NSPrivacyAccessedAPITypeReasons" ./SocialApp.app/PrivacyInfo.xcprivacy

Array {
    CA92.1
    1C8F.1
    C56D.1
}