扎网恢恢

2022-08-12

A version of this article appears on Aug. 12, 2022 as a member article for SSPAI. Learn more or subscribe

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

在这篇题为《Instagram 和 Facebook 可以跟踪应用浏览器中任何网站的任何行为》的文章中,作者 Felix Krause 通过一些简短的脚本截获了 iOS 版 Facebook、Facebook Messenger 和 Instagram 的「小动作」。

Krause 发现,每当用户在这些应用中点击外部链接时,Facebook 的定制浏览器都会向打开的网页注入一串代码。通过这些代码,Facebook 能够监控各类用户操作(如文本选择、表单输入等),并收集用户的行为信息用于定向推送广告,真可谓扎网恢恢、疏而不漏。

Krause 使用自制脚本截获的 Facebook 注入脚本

不过,在 iOS 这个号称安全隐私的环境中,Facebook 是怎么做到「暗渡陈仓」的呢?这涉及一些应用开发相关的背景知识,但并不艰涩。

在 iOS 应用中,开发者要向用户展示一个外部网页,有两种选择:

一种比较新的选择是 Safari View Controller,从 2015 年的 iOS 9 开始支持。这相当于在应用里塞进一个精简版的 Safari 浏览器,优点也自然在于可以调用 Safari 的内置功能,包括密码填充、阅读器、检测欺诈网站、过滤广告等。但相应地,缺点则在于浏览界面只能长成苹果指定的样子,开发者能做的最多是改改颜色。

另一种比较传统的选择是 WKWebView(iOS 8 之前有个更老的 UIWebView,但已停止支持并禁止使用了)。这个功能的本意在于将网页内容直接作为一种元素嵌入到应用界面中。例如,新闻应用可以用它来显示文章页;苹果 iCloud 设置、音乐 app 的部分界面也是用这个功能显示的。与此用途相匹配,WKWebView 具有远超 Safari View Controller 的定制性:开发者可以随意调整网页的内容和功能,也有办法获知用户的操作和输入。

WKWebView(左)和 Safari View Controller(右)(来源:苹果)

根据苹果的建议,如果目的只是让用户访问互联网页面,那么应当优先使用 Safari View Controller。但实践中,大量开发商仍然坚持使用 WKWebView 充当应用内浏览器,这既包括本次事件的主角 Facebook,也包括微信、淘宝、微博等国内用户的老朋友。

(在 Android 中,应用内浏览器也有两种选择:WebView 相当于 iOS 中的 WKWebView,提供更强的定制化能力;而 Android Custom Tabs 则接近 Safari View Controller,提供更接近常规浏览器的界面。与苹果类似,谷歌的建议也是仅当网页由开发者自己控制、出于将网页嵌入界面元素的目的,才使用 WebView,否则应该使用 Custom Tabs。)

客观地说,苹果给 Safari View Controller 提供的能力着实有限,用 WKWebView 也未必就是居心叵测。例如,微信就是通过 WKWebView 提供的扩展能力,让第三方网页端对接朋友圈分享、扫码、卡券、支付等微信生态下的功能。但应用通过 WKWebView 所掌握的权力也确实缺乏边界,从而为各种滥用行为提供了动机、打开了方便之门。

此外,Facebook 虽然难脱其咎,苹果、网页开发者和用户自己也都有可以吸取教训、考虑更周之处。

首先是应用商店审核的缺位。 事情曝光后的讨论中,集中出现的疑问就是,一向以在审核中「层层加码」出名的 App Store,怎么就放过了这种偷鸡摸狗的行为呢?如作者在原文中所提及,App Store 规则中实际是有一些原则性建议的,但并没有强制执行。其实,只要简明地要求「如果使用 WKWebView 显示完整网页,除非网页由开发者控制或者用户明确要求,否则禁止篡改网页的内容和功能」,既不会影响大多数合理使用场景,又能避免 Facebook 这样的滥用行为。

苹果对用户的教育也不到位。 环顾身边,有几个用户能识别两种类型的应用内浏览器,并且知道它们的区别呢?虽然这看似是只有开发者会关心、高度技术向的话题,但如果从此次事件能得出什么一般性经验,那就是开发层面的选择,会对用户的隐私保护产生直接影响,并且一些厂商正在主动利用用户的不知情。苹果对隐私的宣传不应仅限于喊几句高大的口号,拍几条炫酷的广告,而是切实普及安全常识、帮助用户提高技能和素养。

还有观点提出,网页开发者也应当有所作为。 例如,可以在网页中使用更为严格的「内容安全政策」(Content Security Policy,CSP),直接拒绝加载来自站外域名的脚本。此外,还可以检测当前的浏览器环境,如果发现用户正在使用内嵌浏览器,则发出警告或停止提供涉及敏感信息的功能。谷歌从去年已经开始这么做了:如果发现用户在内嵌浏览器中进行谷歌账户的登录和授权,则会主动提示和屏蔽

实际上,Facebook 在此事中的手法是比较「笨重」的;追踪行为发生在用户打开网页之后。环顾其他一些臭名昭著的应用就会发现,想实现对链接的跟踪和拦截,门路实在太多。例如,无论是推特还是微博,都会强制给用户发出的链接加一层短网址跳转(分别是 t.cot.cn)。这样,点击链接首先访问的就是推特和微博控制的服务器,然后再被重定向到原始网址。因此,哪怕推特的 iOS 客户端看似一股清流,使用了 Safari View Controller 而不是自定义 WebView,用户的访问行为仍然在它的监控之下。

当然,还有一位独孤求败的集大成者——微信。且不说监控内置浏览器的内容,把所谓「不安全」链接重定向到 weixin110.qq.com,你肯定也知道自己并不是为了卖萌才去「復制描述后咑開淘寶」和「fu 製链接打开 Dou 吟搜索」,对吧?(详见——如果你看得懂的话——《微信外部链接内容管理规范》。)

因此,真正能靠得住的,可能只有用户自己的判断力和「好习惯」:每当在应用内收到第三方网站的链接、或者需要访问外部页面时,除非需要调用应用内置功能(例如支付、绑定等),否则应该尽可能把链接复制到「正常」的外部浏览器中打开(链接本身也需要审视,去除无用的跳转和追踪参数)。这当然又是一个本不应由用户专门学习的技能,但「卫生环境」如此,我们能做的也无非是做好个人防护了。