编注:本文原文发表于 Felix Krause 的个人博客,文章的翻译、注释以及发布均已得到作者同意。为了补充一些细节以及便于普通读者理解,本文对原文有一定程度的修改。


本周一篇指责 Facebook 在旗下应用内跟踪用户网页浏览的文章,引起了英文技术社区的热议。

整个事件大概就是,Meta 公司旗下的 Instagram 和 Facebook 应用程序的 iOS 版本被隐私安全专家 Felix Krause 发现,它们会用程序内的定制化浏览器尝试跟踪用户在其他第三方网页中的交互和输入,无论是简单地浏览网页,还是输入密码、住址等机密信息,不仅有害于用户隐私,还会给用户带来不少的风险。

注意:为简单起见,在下文中我们将使用「Instagram」来指代 「Meta」或 「Facebook」。

TL; DR:

Instagram 做了什么?

  • Instagram 通过内置的、经过修改的浏览器,而非 iOS 自带的 Safari 来呈现外部网站的链接。
  • Instagram 内置的经过修改的浏览器呈现外部网站时,将允许 Instagram 监控外部网站上发生的一切,无需用户或网站提供者的同意。
  • Instagram 应用程序将他们的追踪代码植入到浏览器中显示的所有的网站中和可点触的广告中,让他们能够监控所有的用户交互行为,例如点击按钮和链接、文本选择、屏幕截图以及任何表单输入的信息,例如密码、地址和信用卡号码等。

会发生什么?

  • Instagram 真的可以读取我在网上做的任何事吗?不能,只有当你从 Instagram 内部打开链接或者广告时,它才能读取并监视你的在线活动。
  • Instagram 真的窃取了我的密码,住址,和信用卡密码信息吗?没有,我不能肯定 Instagram 正在追踪的具体是哪类数据,但这篇文章旨在展示他们会在你不知情的情况下追踪你。过去的种种迹象表明,如果一家公司可以以合法、免费且不需要取得用户知情同意的的方式获取数据,那么他们就会对该数据进行追踪。
  • 我该如何保护自己?简单来说就是:无论何时,当你在 Instagram (或者 Facebook/Messenger)内部打开网页链接或者广告时,请确保自己点击右下角的按钮——将该网页在 Safari 中打开。想了解更详细的信息,请继续阅读。
  • Instagram 这么做是有什么目的吗?我没办法猜到他们内部是怎么想的。我想说的是,构建自己的应用程序内置浏览器要花大量时间去编程和维护,这个时间成本远远大于直接使用过去 7 年以隐私和用户友好著称的 iPhone 自带的浏览器。

些背景知识

编注:「一些背景知识」部分由编辑 @广陵止息 补充写作,以便于普通读者能好地理解整个事件,这部分内容不能代表 Felix Krause 本人的观点。

Instagram 的主要营收来自于广告

Instagram 的收入财报,图源

Instagram 的主要营收来自于广告,可以看到 2021 年 Instagram 的广告收入高达 1149 亿美元,相比 2020 年增长了 36.55%,占据全公司收入的 97.46%,所以与其说 Instagram 是媒体服务公司,不如说它是广告公司。

App 跟踪透明度功能会影响广告收入

Apple 在 2021 年发布的 iOS 14.5 中上线了一个名叫「App 跟踪透明度」的功能,通过该功能用户可以选择性地允许部分应用跨(隶属于其他公司)应用跟踪用户数据。

关联阅读:苹果大战 Facebook,个人隐私的正义黎明?

在这个功能发布以后,Instagram 的 CEO 马克・扎克伯格(Mark Zuckerberg)报告该公司将在 2022 年损失 100 亿美元营收;而市场研究公司 Lotame 的报告显示:

将在第二年对这些企业产生近 160 亿美元的影响……大部分影响(81%)仍会是 Meta……而按照 81% 的比例计算,Meta 受到的冲击约为 128 亿美元。

反馈在财报上表现为,今年第二季度的 Instagram 的营收相比于去年同期减少了 1%,官方也承认 App 跟踪透明度的功能影响了广告营收。

关于作者 Felix Krause

Felix Krause 是开源工具 fastlane 的创始人,该工具可以用于构建和发布手机应用程序。他本人不仅精通 iOS 应用程序开发,而且也专攻隐私研究,曾于各大平台发布关于隐私保护的文章

为什么 Instagram 会用这种方法跟踪我们?

通过网页跟踪用户早在移动互联网盛行之前就已经是一个非常常规的手段了,跟踪用户的方法有很多,但其中最出名的就是通过第三方 cookies 进行跟踪。随着各大浏览器厂商开始默认阻止第三方 cookies,这种跟踪方式已经越来越难跟踪用户了。

关联阅读:

而在 HTTPS 协议在覆盖绝大多数网站以前,一些互联网服务供应商(ISP)会将他们的追踪/广告代码植入到所有网站中;但这样的方式在 HTTPS 兴起以后就也不是一个可靠的选择了,因为 HTTPS 能阻止第三方公司查看和修改用户收到的具体信息。

不过,在移动网络和 HTTPS 盛行以后,想要只跟踪用户电脑上浏览的网页可就不够了,还需要了解用户在每个 App 里都在看些什么,最常见的手法就是给每个用户的手机分配以一个广告跟踪符,在 iOS 系统上 iOS 会自动为每台设备随机生成的一串代码(下文简称 IDFA),看上去就像这样:

7D902I08D-7846-4CA4-TE6P-83369125YFDC

IDFA 就像是一台设备的身份证,用户在应用内的一切操作,都可以将被应用记录下来,并且与 IDFA 绑定,就形成这台设备的行为数据。在 iOS 14.5 以前,任何的 App 都可以自由访问 IDFA,而这样就会导致一个问题,所有的 App 都能知道用户的行为数据且了解用户的偏好。从 iOS 14.5 开始 App 追踪透明度功能正式上线,从这时开始所有的应用程序需要先获得用户的许可,才可以然后才能跨应用追踪用户数据。虽然 App 追踪透明度功能并不能完全防止一个公司跟踪我们,但是至少还是能减少跟踪面的,所以 App 追踪透明度功能上线以后 Instagram 和 Apple 之间的嘴炮从未停歇过:


编注:以下内容为 Felix Krause 的个人博客的译文,除了补充必要的解释信息外,仅代表作者 Felix Krause 本人的观点。

苹果公司的 iPhone 警告信息每年会让 Instagram 损失100亿美元。

Facebook 抱怨说,苹果公司的 App 追踪透明度(ATT)利好了那些像谷歌这样的公司,因为这个功能「可以让浏览器从应用跟踪提示中豁免」。

由于反跟踪功能内置于 iOS,所以你在 iOS 上访问的网站不会触发追踪提示。—— Daring Fireball & MacWorld

Facebook 用消息轰炸其用户,乞求他们重新将追踪功能打开。它威胁对苹果提起反垄断诉讼。它让小企业为用户追踪的行为辩护,因为当一家巨大的公司监控着数十亿用户时,小公司也得为自己谋求发展之道。—— EFF《Facebook 声称苹果过于强大,但他们是对的》

Instagram 确实遵循了 App 追踪透明度(ATT)的规则,但从第三方网站和第三应用程序获取数据对于 Instagram 依然是维持广告营收的一个很重要的方向。随着网页浏览器和 iOS 将越来越多的隐私控制权交到用户手中,Instagram 对监控外部网站的需求自然有增无减。而 Instagram 拥有十亿活跃用户,通过将追踪代码植入从 Instagram 和 Facebook 应用程序内置浏览器打开的每一个第三方网站,Instagram 最终能获取的数据量是惊人的。

不过,本文的讨论范围仅限在如何实现这种行为以及在技术上什么是可能实现的,暂不在法律层面上讨论这个行为。

被植入的是什么?

Instagram 应用程序植入的外部 JavaScript 文件是一个用于连接了外部网站和 Instagram 应用的「桥梁」。根据 Meta 为了回应本篇文章向作者提供的信息,这个「桥梁」会被用于汇总各种事件,比如:在线购买,稍后这些信息将被用于 Instagram 平台的定向广告和受众评估。

原作者的声明

我并没有 Instagram 到底收集了哪些数据的精确列表。我只是有证据证明 Instagram 和 Facebook 应用程序在未经用户许可的情况下,主动运行了一个 JavaScript 指令并额外注入了一个JavaScript SDK,用于跟踪用户的文本选择。Instagram 已经这么做了,他们还完全可以再植入其他的任意 JavaScript 代码。此外,Instagram 应用程序本身可以很好地防止中间人攻击,只有通过修改他们的 Android 安装包文件来去除证书锁定并且在模拟器中运行才可能进行中间人攻击。

总之本文的目的不在于详细列出他们收集的数据种类,而是去强调当用了 app 内置浏览器后可能造成的隐私和安全问题,并且去证明 Instagram 等的 app 已经在利用这一漏洞了。

关于被植入的代码和背后的实现原理,在上周五的派周报中已经详细分析过了,因此这里就不做展开了,大家感兴趣的话可以移步那篇文章做进一步的了解。

关联阅读:派周报 | 本周会员内容提要;跑题:扎网恢恢

而利用这一漏洞,在用户使用类似 Instagram 等的 app 内置的浏览器时可能会有如下的风险和问题:

  • 隐私 & 分析:主应用程序能够追踪网站上的几乎所有动态,包括每一次点触、输入、滑动的行为、复制粘贴的内容,以及类似于在线购买的信息。
  • 窃取用户凭证:物理地址,API 密钥等。
  • 广告 & 推荐码:主应用程序可以向这些网站植入广告,或者替换广告的 API 密钥以窃取营收,又或者是在所有 URL 中加入你的推荐码,而这种情况以前发生过
  • 安全:浏览器行业已经花了许多年去优化网络用户的安全,比如向用户显示 HTTPS 的加密状态,警告用户网站是可疑网站或者网站本身未加密等等。
  • 向第三方网站植入额外的 JavaScript 代码可能会导致额外的问题和故障,也会有风险导致网站崩溃。
  • 用户无法使用浏览器扩展程序和内容拦截器。
  • 深度链接 (Deep linking)在大多数情况下不能起效。
  • 无法使用如 Email、AirDrop 等方法将该链接分享到其他平台。

虽然,Instagram 的内置浏览器支持自动填写你的住址和付款方式。但,没有任何理由去支撑这个功能以 JavaScript 注入的形式存在,这个功能目前已经内置于操作系统或者浏览器里了。

作为用户应该如何保护自己?

避开 app 内的网页视图

大多数 app 内置浏览器都有办法将网站跳转至 Safari 打开。一旦你在 app 中打开了某个网站,只需点击如图所示的「在浏览器中打开」 。如果这一按键并不存在,你就需要去将网页 URL 复制粘贴到你的浏览器中去打开了。

使用网页版

大多数社交平台,包括 Instagram 和 Facebook,都提供了算得上能用的移动网络版本,提供了和 app 类似的功能集合。 你可以在 iOS Safari 输入并打开 https://instagram.com 登陆以后就可以无障碍使用 Instagram 里。

作为网站提供者,你该如何保护自己?

在 Instagram 解决这个问题之前 ,如果他们想解决的话,你可以轻松骗过 Instagram 和 Facebook 应用程序——只需要让应用程序相信他们的追踪代码已经被安装过了,因此只要在你的 HTML 代码当中加上这些内容就可以了:

<span id="iab-pcm-sdk"></span>
<span id="iab-autofill-sdk"></span>

另外,如果还想要防止 Instagram 追踪你网站用户的文本选择活动的话,还需要加上这些:

const originalEventListener = document.addEventListener
document.addEventListener = function(a, b) {
    if (b.toString().indexOf("messageHandlers.fb_getSelection") > -1) {
        return null;
    }
    return originalEventListener.apply(this, arguments);
}

这并不会从实质上解决 Instagram 针对你的网站运行 JavaScript 代码的问题,但至少能防止被植入额外的 JS 脚本,也可以减少跟踪面。

同样,对于一个 app 来说,通过检查用户代理 (user agent)来检测当前浏览器是否是 Instagram/Facebook app 内置浏览器也很容易,但是我想不到一个很好的办法让这些 app 内的浏览器自动跳转到 Safari 中,如果有的话欢迎通过这个渠道告诉原作者

大公司可以怎么做

对于苹果

苹果在搭建他们的平台时将用户隐私谨记于心。他们有四条隐私原则,其中之一如下:

用户透明度和控制 (User Transparency and Control): 确保用户知道何种数据会被共享,以及数据会被怎样使用,让用户对其可以进行掌控。

—— 苹果隐私PDF

在撰写本文时,并没有任何的 AppStore 审核规则禁止任何公司建立自己的 app 内置浏览器去追踪用户,读取用户输入,并植入额外的广告和第三方网站。但是,苹果很明确的建议使用 SFSafariViewController 来构建应用内的网络浏览器。

避免使用 Web 视图来构建网络浏览器。使用 Web 视图让人们在不离开你的 app 的情形下短暂的进入另一个网页是可以的,但 Safari 仍是人们浏览网页的首要选择。尝试在你的 app 当中复制 Safari 的功能是不必要且不被鼓励的。

—— Apple 人机界面准则 (Apple Human Interface Guidelines)

如果你的应用程序允许用户查看其他网站的内容,请使 SFSafariViewController 控件。如果你的应用程序要自定义、交互或者控制网页内容的显示时,才应该使用 WKWebView 类。

—— Apple SFSafariViewController 文档

采用 App-Bound Domains

App 绑定域 (App-Bound Domains) 是一项出色的新 Webkit 特性,使开发者在使用 WKWebView 控件时能够向用户提供一种更加安全的 app 内置浏览器上网体验。作为一名 app 开发者,你可以定义你的应用程序可以访问哪些域,且所有的网络请求都将仅限于这些域。如果要禁用这种保护,用户必须去 iOS 设置中明确的为该应用程序禁用这项功能。

App 绑定域功能大约 1 年半之前随着 iOS 14 推出,但是它对于开发者来说只是一个可选项,也就是说大部分 iOS 的应用程序并没有用到这项特性。

如果社交类软件想要他们的用户拥有更好的隐私体验,他们有两条路可走:

在 app 内置浏览器中使用 SafariViewController 而不是 WKWebView。SafariViewController 通过在社交类软件的进程以外的空间加载页面,以此来保护用户的数据免受应用程序的侵害。SocialApp 可以因此确保在使用SafariViewController 时可以为其用户提供最佳的用户隐私体验。

选择 App 绑定域。额外增加了 App 绑定域的WKWebView控件将被限制,以确保社交类软件无法使用上述 API 跟踪用户。

我强调了「想要用户有更好的隐私体验」这句话,因为这也是现在正缺失的一部分:在发生社交软件植入追踪代码这件事情以后,App 绑定域应该成为每一个 iOS 应用程序必备的一部分。

在 2022 年 7 月,苹果推出了「Lockdown Mode」旨在为高风险人士提供更好的保护。不幸的是,iOS 「Lockdown Mode」并没有改变 app 内置 WKWebView 控件浏览器的运行模式。我向苹果提交了一份 rdar 文件:rdar://10735684,但对此苹果的回答仅是:「这并不是『Lockdown Mode』被设计用来要做的事」。

苹果可以立即采取的一些措施:

更新应用审核规则 (App Review Rules) ,要求在显示任何第三方网站时使用 SFSafariViewController 控件或 App 绑定域。

除了类似浏览器应用程序以外的少数例外,但这些例外需要额外进行确认:

  • 需要一个额外的审查来确保,这些例外是确有其事需要这样使用的
  • 让用户确认这些额外的权限
  • 第一方网站或内容仍然可以通过使用 WKWebView 控件显示,因为 WKWebView 控件通常被用于 UI 元素,或者该应用修改了他们的第一方内容 (例如自动关闭它们自己的 cookie 横幅)。

我还向 Apple 提交了一个雷达 ( rdar://38109139 ),作为我过去博客文章的一部分内容。

对于 Meta

应该就像 Meta 在 WhatsApp 里所做的那样:不修改第三方网站,使用 Safari 或者 SFSafariViewController 控件来打开第三方网站,这不仅对用户是件好事,还是在商业道德上也是一件对的事情。

我在此前已经通过他们的 Bug Bounty Program (漏洞悬赏计划)披露了这一问题,在几小时之内他们确认他们能够复现这个「问题」, 但在此之后的九个星期里,除了他们让我等待更久的时间,直到他们推出完整的报告以外,我没有听到任何其他的消息。由于对我的后续问题没有任何回应,他们也没有停止向外部网站植入追踪代码,因此我决定在给了他们另外 2 周的提醒之后公开这些信息。

> 暑期征文 数字文具盒 火热征稿中,分享学习方法,拿走现金奖励 🧑🎓

> 实用、好用的 正版软件,少数派为你呈现 🚀