MASTG-TECH-0137: 分析 PrivacyInfo.xcprivacy 文件
一旦你如 检索 PrivacyInfo.xcprivacy 文件中所示获取了隐私清单,你就可以继续分析它了。
让我们以 SocialApp.app/PrivacyInfo.xcprivacy
文件为例。
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>
此 PrivacyInfo.xcprivacy
文件包含
- NSPrivacyAccessedAPITypes:列出了应用程序访问的 API 类型及其 访问原因。 在这种情况下
NSPrivacyAccessedAPICategoryUserDefaults
:UserDefaults
因CA92.1
、1C8F.1
、C56D.1
等原因而被访问。NSPrivacyAccessedAPICategoryActiveKeyboards
:与活动键盘的交互因54BD.1
原因而被访问。
- NSPrivacyCollectedDataTypes:列出了应用程序收集的数据类型以及特定目的。 它还指示收集的数据是否链接到用户的身份(
NSPrivacyCollectedDataTypeLinked
),以及是否用于跟踪目的(NSPrivacyCollectedDataTypeTracking
)。 在这种情况下NSPrivacyCollectedDataTypeName
:收集用户名,目的包括“应用程序功能”和“其他”(链接到用户身份,但不用于跟踪)。NSPrivacyCollectedDataTypeOtherDiagnosticData
:收集其他诊断数据,用于“分析”、“应用程序功能”和“其他”等目的(链接到用户身份,但不用于跟踪)。
- NSPrivacyTracking:表明 SocialApp 使用数据进行跟踪,如应用跟踪透明度框架下所定义的那样。
- NSPrivacyTrackingDomains:列出了用于跟踪目的的域,在本例中包括各种与 SocialApp 相关的域。
您可以使用多种工具和解析器以编程方式读取和分析这些文件。
使用 jq¶
如果您如 将 Plist 文件转换为 JSON 中所述将 PrivacyInfo.xcprivacy
文件转换为 JSON 格式,您可以使用 jq 进行查询。
例如,要提取每个 NSPrivacyAccessedAPIType
的所有 NSPrivacyAccessedAPITypeReasons
cat SocialApp.app/PrivacyInfo.json | jq '.NSPrivacyAccessedAPITypes[] | {api: .NSPrivacyAccessedAPIType, reasons: .NSPrivacyAccessedAPITypeReasons}'
输出结果(为便于阅读已截断)
{
"api": "NSPrivacyAccessedAPICategoryUserDefaults",
"reasons": [
"CA92.1",
"1C8F.1",
"C56D.1"
]
}
{
"api": "NSPrivacyAccessedAPICategorySystemBootTime",
"reasons": [
"35F9.1"
]
}
...
优点包括可读的输出、标准的 JSON 工具和简洁的选择语法。 缺点是日期和原始数据 Blob 会变成字符串,数字精度可能会发生变化,并且注释和键顺序会丢失。 如果你需要保留 plist 特定的类型,请考虑使用 Python 的 plistlib 模块。
使用 plistlib¶
使用 Python 内置的 plistlib
模块读取和操作 plist 文件,包括 PrivacyInfo.xcprivacy
。
例如,要提取每个 NSPrivacyAccessedAPIType
的 NSPrivacyAccessedAPITypeReasons
import plistlib
import json
# load the .xcprivacy plist
with open('SocialApp.app/PrivacyInfo.xcprivacy', 'rb') as fp:
data = plistlib.load(fp)
# extract and print each API and its reasons in 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))
输出为(为便于阅读已截断)
{"api": "NSPrivacyAccessedAPICategoryUserDefaults", "reasons": ["CA92.1", "1C8F.1", "C56D.1"]}
{"api": "NSPrivacyAccessedAPICategorySystemBootTime", "reasons": ["35F9.1"]}
...
使用 PlistBuddy¶
使用 PlistBuddy 直接读取和操作 plist 文件,无需将其转换为 JSON,包括 PrivacyInfo.xcprivacy
。
例如,您可以使用以下命令读取 NSPrivacyAccessedAPITypes
/usr/libexec/PlistBuddy -c "Print NSPrivacyAccessedAPITypes" ./SocialApp.app/PrivacyInfo.xcprivacy
Array {
Dict {
NSPrivacyAccessedAPIType = NSPrivacyAccessedAPICategoryUserDefaults
NSPrivacyAccessedAPITypeReasons = Array {
CA92.1
1C8F.1
C56D.1
}
}
...
}
您可以更深入地研究该文件以提取更具体的信息。例如,您可以通过以下方式获取第一个 NSPrivacyAccessedAPITypes
元素(索引 0
)的 NSPrivacyAccessedAPITypeReasons
/usr/libexec/PlistBuddy -c "Print NSPrivacyAccessedAPITypes:0:NSPrivacyAccessedAPITypeReasons" ./SocialApp.app/PrivacyInfo.xcprivacy
Array {
CA92.1
1C8F.1
C56D.1
}