Flutter 上了 Apple 第三方重大列表,2024 春季 iOS 的隐私清单究竟是什么?

这个话题的起因来自 2023 年 WWDC 之后苹果发布的「App Store 提交隐私更新」政策,政策主要提出了两点:第三方 SDK 隐私清单和签名需要提供必要理由的 API 流程

其实先简单总结,就是 Apple 想通过隐私清单来进一步提升用户数据收集和使用的透明度,包括 required reason API 也是算是属于隐私清单里的内容。

那这个和标题里的 Flutter 有什么关系?因为跟随此次隐私清单升级, Apple 上线了一个**对用户隐私产生重大影响的第三方 SDK 列表** ,而在这列表恰好就有 Flutter 的存在,并且里面接近 1/3 是和 Flutter 相关的 Plugin ,例如 connectivity_pulusdevice_info_plusfluttertoastshared_preferences_iossqflitewebview_flutter_wkwebviewurl_launcher 等等。

列表地址:https://developer.apple.com/support/third-party-SDK-requirements/

这就很懵逼了,是 Flutter 做了什么「天怒人怨」的问题,还是 Apple 故意针对 Flutter 呢?那在聊这个问题之前,我们首先需要简单了解下,这次的隐私标签里主要涉及的是什么?

这个问题不只是对 Flutter ,其实对于 iOS 来说 2024 在 Xcode15 上也属于最重要的适配需求

隐私清单

**聊隐私清单,首先最主要是就是第三方隐私清单(privacy manifest) **,属于让 SDK 开发人员提供他们 SDK 的一些数据收集行为,然后 App 开发者在集成各种 SDK 之后,可以得到一份详细的隐私清单,如下图是 SDK 里声明的隐私清单。

隐私清单的作用是帮助开发者了解第三方 SDK 如何使用数据,这样开发者在向 App Store 提交审核时,Xcode 可以将第三方 SDK 中的隐私清单合并,然后导出一个 PDF 报告汇总。

通过这份隐私清单报告,开发者就可以在 App Store 提交审核时,更方便地提供「隐私标签」,如下图所示就是 iOS 14 时 App Store 推出的功能,当时就要求 App 开发者在 App Store 后台声明应用的数据收集和使用场景,让用户在应用详情页面知道 App 收集了什么和做了什么。

那么首先可以知道,SDK 隐私清单的作用,就是让 App 开发者可以根据生成的清单,更好精确和方便地管理自己 App 的隐私标签,一般情况下大概会有:

  • 收集的数据类型

  • 数据是否能关联到用户

  • 数据是否用于跟踪活动

  • 收集此数据的理由

其中关于数据类型可见:https://developer.apple.com/documentation/bundleresources/privacy_manifest_files/describing_data_use_in_privacy_manifests

那如果我不需要隐私清单来管理隐私标签,就可以理会这次的隐私清单的事情了呢?那答案肯定不是,因为隐私标签还包含了其他东西,比如必要理由的 API 声明、声明跟踪域名和第三方 SDK 签名等。

必要理由的 API 声明

首先这个主要是 Apple 新搞了一个 API 分类使用这一个 API 分类你需要在隐私清单里说明使用理由, Apple 这么做的目的是主要是想规范 App 随意通过这些 API 做 fingerprinting 识别的行为,相关的 API 也不多,大概涉及:

  • File timestamp APIs
  • System boot time APIs
  • Disk space APIs
  • Active keyboard APIs
  • User defaults APIs

如果 SDK 和 App 里用到了分类里的这些 API ,你就需要在隐私列表里填写原因,例如:

使用了 Disk space APIs 的 systemFreeSize ,在写入前判断磁盘空间大小,那么就需要引用列表里的 E174.1 条款,如下图写明使用的原因。

从目前看,类似 UserDefaultsstat 等 API 还是很容易被使用到,所以 Required Reason API 这部分应该都是跑不掉的

条款列表可见:https://developer.apple.com/documentation/bundleresources/privacy_manifest_files/describing_use_of_required_reason_api

声明跟踪域名

隐私清单其实一定程度也算是应用跟踪透明度 (ATT) 的内容之一,而本次更新,如果用户未通过 App Tracking Transparency (ATT) 授予权限, Apple 就会阻止对追踪域(Tracking Domains)的网络请求。

简单来说,就是需要定义一个 NSPrivacyTrackingDomains 列表,这样但用户不同意 ATT 权限时, 系统就会阻止这些域名的任何调用,所以 SDK 上如果有类似相关跟踪的域名调用,也需要区分声明好跟踪域名和非跟踪域名。

当然,不管你是否利用 ATT 的定义进行跟踪,你都必须在隐私清单中列出收集的数据类型和原因,因为这个和 ATT 没有必然关系,只是如果使用了 ATT 的域名,在这里需要额外声明来符合权限, ATT 在 iOS 17 上实际并没有什么变化

这里的跟踪定义是:能狗将你收集的数据与其他公司 App 收集的数据相关联,比如使用了 IDFV 也算跟踪,。

只是这里我有个疑问,如果我不把 ATT 的相关收集域名放到 NSPrivacyTrackingDomains 列表,其实 Apple 是审核是不是也无法明确发现呢?那么我不做是不是也是可以?

第三方 SDK 签名

本次跟随隐私清单而来的还有第三方 SDK 签名,这是我们以前一直忽略的东西,而 Apple 的目的也很直接,就是希望通过签名认证的方式来确保 SDK 不会被篡改,简单的说就是 SDK 发布时带有 _CodeSignature

需要签名,肯定是 SDK 包含了二进制依赖,没有二进制依赖其实并不需要考虑签名问题

这里的签名其实分 Apple Developer Program 签名和自签名,如果你的 SDK 使用的是 Apple Developer Program ,简单来说就是可以得到更安全可靠的认知加持,安全性拉满,但是如果你采用的是 codesign 自签名,那么也不是不行,就是你自己保管好签名认证的方式。

echo "Build Archive Device Slice"
xcodebuild clean archive -sdk iphoneos -destination 'generic/platform=iOS'[...]
echo "Build Archive Simulator Slice"
xcodebuild clean archive -sdk iphonesimulator -destination 'generic/platform=iOS Simulator' [...]
echo "Create XCFramework"
xcodebuild -create-xcframework [...] -output <YOUR.xcframework>
echo "Codesign XCFramework"
codesign --timestamp -v --sign "<YOUR CERTIFICATE (ABCXYZ)>" "<YOUR.xcframework>"

经过签名认证后的 SDK ,在 Xcode15 会显示对应的 Signature 信息,如果一旦发现本次前面和上次不一致,那么Xcode 就会让编译失败并弹出警告。

当然,如果 SDK 的签名变更符合你预期,比如 SDK 维护人员发生了变化,从而导致证书发生变化,那么你也可以通过接受变更的方式也同意更改。总的来说目前这个阶段签名并不是一定要官方,甚至不一定就强制要签名,Apple 「鼓励】所有 SDK 使用签名,但影响隐私的 SDK 一定要签名,特别是前面提到列表里的

目前来说,App Store 已经开始检查最近提交的 App 是否包含影响隐私的 SDK ,如果影响隐私的 SDK 不包含签名和隐私清单,Apple 将向应用开发人员发送提醒邮件,包括提供必要理由的 API 部分,最后会在 2024 年春季开始要求审核。

更多官方资料:

  • https://developer.apple.com/documentation/bundleresources/privacy_manifest_files/describing_use_of_required_reason_api#4278397
  • https://developer.apple.com/documentation/Xcode/verifying-the-origin-of-your-xcframeworks
  • https://developer.apple.com/documentation/bundleresources/privacy_manifest_files/describing_data_use_in_privacy_manifests?language=objc

Flutter

那本次隐私清单对于 Flutter 来说,最大的影响就是大量 Flutter Plugin 被挂上了 Apple 官方的用户隐私产生重大影响的第三方 SDK 列表,因为上了列表,就被认定为是影响隐私的 SDK,那么隐私清单是跑不了的了,另外如果有二进制依赖还需要满足签名条件,所以这对于 Flutter 来说在 iOS 17的适配上无疑「雪上加霜」,可以看到目前官方开了很多关于官方 package 的 iOS 隐私清单适配 issue 。

对于 Flutter Engine 部分,其实官方适配隐私清单难度并不大,目前调查完 iOS 上 Flutter Engine 主要需要适配的有:

  • File timestamps :

    • C617.1 用于 FlutterAppDelegate.mm 里的应用状态恢复
    • 0A2A.1 用于实施相关 File 包装器
  • System boot time:

    • 35F9.1 用于各种事件计时和经过时间的计算

目前官方在 #131494 已经表示,会将 PrivacyInfo.xcprivacy 包含在未来 Flutter.framework 中,所以这部分并不需要担心

而在 flutter/packages 部分目前却是有棘手的问题,例如 shared_preferences ,它被列入影响隐私 SDK 列表的原因是因为 NSUserDefaults ,但是 shared_preferences 它本身只是 API 的封装,为了方便 Flutter 开发者调用,它本身是不知道如何/为什么使用它,在 SDK 层面很难在隐私清单描述给出所谓的「收集原因」

另外第三方 Plugin 也可能使用 shared_preferences ,但是 App 开发并不知道它用来做什么,那么如果让 pub 的 Plugin 能描述好隐私清单的内容?

目前官方文档提及:

If you use the API in your third-party SDK’s code, then you need to report the API in your third-party SDK’s privacy manifest file

这听起来像是只要拥有它的代码就需要标记出它的原因,但是实际上 Plugin 不知道该层存储的数据是什么或如何被使用。

对于 “收集” 的定义目前很模糊,类似的还有 webview_flutterwebview_flutter 本身不收集任何内容,但是App 可以用来 webview_flutter 收集浏览历史记录,然后这如何在 SDK 的隐私清单里去体现?

感觉目前的 iOS 要求没有很明确,适配方向不够清晰。

最后,目前文档说他们「鼓励」每个人都采用该清单,而对于在隐私列表的 SDK 看起来是强制的,但是如何选择这些 SDK 的规则目前也看不到,所以只能等待后续和 Apple 的沟通回复。

更多进度可见:

  • https://github.com/flutter/flutter/issues/131940
  • https://github.com/flutter/flutter/issues/131495
  • https://github.com/flutter/flutter/issues/131494

最后

总结一下,本次 iOS 隐私清单主要覆盖的有:

  • SDK 提供隐私清单的数据收集类型、使用描述和用途
  • 必要理由的 API 需要提供使用“代码”和原因
  • ATT 跟踪添加域名区分
  • 第三方 SDK 签名

这里面 SDK 提供的隐私清单,我个人理解:

  • 首要是用来给 App 打包后,通过导出的 pdf 参考管理隐私标签
  • 其次对于必要理由的 API 的使用附带使用说明
  • 关于 ATT 收集相关的数据域名添加到清单进行区分,至于你不写是否会被抓住不好说
  • 第三方 SDK 签名不是强制,也可以自签名,前提是你不是在官方影响隐私 SDK 列表中
  • 如果你 SDK 没有二进制,没有使用必要理由的 API,理论上其实甚至可以不管什么隐私清单和签名,因为你正常也进不去官方的影响隐私 SDK 列表。

本次更多是探讨,因为官方的描述和文档内容上其实并不严谨,甚至有很多模糊的地方。

猜你喜欢

转载自blog.csdn.net/ZuoYueLiang/article/details/134976733