什么是第三方?
一个网站完全自包含的情况相当罕见。HTTP Web Almanac 显示,大多数网站(约 95%)都包含一些第三方内容。
Almanac 将第三方内容定义为托管在共享且公开的来源上的内容,该来源被各种网站广泛使用,并且不受单个网站所有者的影响。这些可能是图片或其他媒体,例如视频、字体或脚本。图片和脚本加起来比其他所有内容都多。第三方内容对于开发网站并非必不可少,但它也可能非常有用;您几乎肯定会使用从公共共享服务器加载的内容,无论是 Web 字体、视频的嵌入式 iframe、广告还是 JavaScript 库。例如,您可能正在使用从 Google Fonts 提供的 Web 字体,或者使用 Google Analytics 衡量分析数据;您可能添加了来自社交网络的“赞”按钮或“使用…账号登录”按钮;您可能正在嵌入地图或视频,或者通过第三方服务处理购物;您可能正在通过第三方监控工具跟踪错误并为您的开发团队记录日志。
出于隐私目的,考虑一个稍微不同且不那么广泛的定义会很有用:第三方资源,特别是第三方脚本,是从共享且公开的来源提供的,并被广泛使用,如上所述,但也是由网站所有者以外的其他人编写的。第三方作者身份方面是考虑如何保护用户隐私免受他人侵害时的关键。这将引导您考虑存在的风险,然后根据这些风险决定如何或是否使用第三方资源。正如已经讨论的那样,这些内容将帮助您了解上下文,从而了解您需要做出的权衡以及它们的含义。
这与通常讨论“第三方资源”时的含义不太一样:第一方和第三方之间的区别实际上是关于使用事物的上下文。从另一个网站加载的脚本是第三方资源,并且加载该脚本的 HTTP 请求可能包含 Cookie,但这些 Cookie 实际上并不是“第三方 Cookie”;它们只是 Cookie,它们是“第三方”还是“第一方”取决于脚本是在您网站的页面上加载还是在脚本所有者的网站的页面上加载。
我们为什么使用第三方资源?
第三方是为您的网站添加功能的绝佳方式。这可能是向用户公开的功能,也可能是不可见的开发人员功能(例如错误跟踪),但它们减少了您的开发负担,并且脚本本身由其他人维护:您包含的服务的开发团队。这一切都归功于 Web 的可组合性:能够将各个部分组合在一起,形成大于其各部分之和的整体。
HTTP Archive 的 Web Almanac 给出了一个很好的描述
第三方提供了永无止境的图片、视频、字体、工具、库、小部件、跟踪器、广告以及您可以想象到的任何其他可以嵌入到我们的网页中的内容的集合。这使得即使是最不懂技术的人也能够创建内容并将其发布到 Web 上。如果没有第三方,Web 很可能是一个非常枯燥、基于文本的学术媒介,而不是如今对我们许多人的生活如此重要的丰富、沉浸式、复杂的平台。
第三方资源可以做什么?
访问某些信息
当您在您的网站上使用第三方资源时,无论它是什么,都会有一些信息传递给该第三方。例如,如果您包含来自另一个网站的图片,用户浏览器发出的 HTTP 请求将传递一个包含您页面 URL 的 Referer 标头以及用户的 IP 地址。
跨站跟踪
继续使用相同的示例 - 当图片从第三方网站加载时,它可以包含一个 Cookie,并且当用户下次请求该图片时,该 Cookie 将被发送回第三方。这意味着第三方可以知道他们的服务正在您的网站上使用,并且它可以发回一个 Cookie,可能包含该用户的唯一 ID。这意味着当用户下次访问您的网站,或任何其他包含来自该第三方的资源的网站时,该唯一 ID Cookie 将再次发送。这允许第三方建立一个用户访问位置的日志:您的网站、使用相同第三方资源的其他网站,遍布整个 Web。
这就是跨站跟踪:允许第三方收集用户在许多网站上的活动日志,只要这些网站都使用来自同一第三方的资源。这可能是字体、图片或样式表 - 所有静态资源。它也可能是动态资源:一段脚本、社交媒体按钮、广告。包含的脚本可以收集更多信息,因为它是动态的:它可以检查用户的浏览器和环境并将该数据传递回其发起者。任何脚本都可以在一定程度上做到这一点,不以脚本形式出现的动态资源也可以做到,例如社交媒体嵌入或广告或分享按钮。如果您查看热门网站上 Cookie 横幅的详细信息,您可以看到一个组织列表,这些组织可能会向您的用户添加跟踪 Cookie,以建立他们活动的照片,从而创建该用户的个人资料。可能有数百个组织。如果第三方免费提供服务,那么他们这样做在经济上可行的一种方式是因为他们收集然后利用这些数据获利。
《目标隐私威胁模型》是一份有用的指南,可用于了解浏览器应保护其用户免受哪些类型的隐私问题的影响。这是一份在撰写本文时仍在讨论中的文档,但它给出了一些对现有隐私威胁类型的高级分类。来自第三方资源的风险主要是“不必要的跨站识别”,即网站可以在多个站点上识别同一用户,以及“敏感信息泄露”,即网站可以收集用户认为敏感的信息。
这是一个关键区别:即使第三方没有从中收集额外的敏感信息,不必要的跨站识别也是有害的,因为它剥夺了用户对其身份的控制权。访问用户的引荐来源网址、IP 地址和 Cookie 本身就是不必要的泄露。使用第三方资源需要规划如何在保护隐私的方式下使用它们。部分工作由您作为网站开发人员负责,部分工作由浏览器在其作为用户代理的角色中完成;也就是说,代表用户工作的代理,以尽可能避免敏感信息泄露和不必要的跨站识别。下面我们将更详细地了解浏览器级别和网站开发级别的缓解措施和方法。
服务器端第三方代码
我们早期对第三方的定义故意更改了 HTTP Almanac 的客户端方法(这对于他们的报告来说是合适的!),以包括第三方作者身份,因为从隐私角度来看,第三方是任何知道您的用户信息的非您的人。
这确实包括在服务器以及客户端上为您提供服务的第三方。从隐私的角度来看,第三方库(例如从 NPM 或 Composer 或 NuGet 包含的内容)也很重要,需要理解。您的依赖项是否将数据传递到您的边界之外?如果您将数据传递给日志服务或远程托管的数据库,如果您包含的库也“电话回家”给他们的作者,那么这些库可能处于侵犯用户隐私的位置,因此需要对其进行审核。基于服务器的第三方通常必须由您将用户数据交给他们,这意味着他们接触到的数据更多地受您的控制。相比之下,基于客户端的第三方(您的网站上包含的脚本或 HTTP 资源,由用户的浏览器获取)可以直接从用户那里收集一些数据,而无需您调解收集过程。本模块的大部分内容将关注于如何识别您选择包含并让用户接触的那些客户端第三方,正是因为您可能进行的调解较少。但是,值得考虑保护您的服务器端代码,以便您了解来自服务器端代码的出站通信,并且可以记录或阻止任何意外的通信。关于如何准确执行此操作的详细信息超出了本文的范围(并且非常依赖于您的服务器设置),但这又是您的安全和隐私立场的另一部分。
为什么您需要小心第三方?
第三方脚本和功能非常重要,我们作为 Web 开发人员的目标应该是集成这些内容,而不是避开它们!但是存在潜在的问题。第三方内容可能会造成性能问题,并且还可能造成安全问题,因为您正在将外部服务引入您的信任边界内。但是第三方内容也可能造成隐私问题!
当我们谈论 Web 上的第三方资源时,将安全问题(除其他外)视为第三方可以从您的公司窃取数据的情况很有用,并将其与隐私问题进行对比,隐私问题(除其他外)是指您包含的第三方在未经您(或他们)同意的情况下窃取或获得访问您的用户数据的权限的情况。
安全问题的一个示例是“网络撇油器”窃取信用卡信息 - 包含在用户输入信用卡详细信息的页面中的第三方资源可能会窃取这些信用卡详细信息并将其发送给恶意第三方。创建这些撇油器脚本的人在找出隐藏它们的位置方面非常有创造力。一份摘要描述了撇油器脚本是如何隐藏在第三方内容中的,例如用于网站徽标、网站图标和社交媒体网络的图片、jQuery、Modernizr 和 Google Tag Manager 等流行的库、实时聊天窗口等网站小部件以及 CSS 文件。
隐私问题略有不同。这些第三方是您产品的一部分;为了维护用户对您的信任,您需要确信您的用户可以信任他们。如果您使用的第三方收集有关您用户的数据,然后滥用这些数据,或者使其难以删除或发现,或者遭受数据泄露,或者违反用户的期望,那么您的用户很可能会认为这是他们对您的服务的信任破裂,而不仅仅是对第三方的信任破裂。这关系到您的声誉和关系。这就是为什么重要的是要问自己:您信任您在网站上使用的第三方吗?
第三方有哪些示例?
我们通常在讨论“第三方”,但实际上有不同的类型,并且它们可以访问不同数量的用户数据。例如,与添加 <iframe>
或 <script>
元素相比,将从不同服务器加载的 <img>
元素添加到您的 HTML 中,将为该服务器提供有关您的用户的不同信息。这些是示例而不是详尽的列表,但了解您的网站可以使用的不同类型的第三方项目之间的区别很有用。
请求跨站资源
跨站资源是您网站上从不同站点加载的任何内容,并且不是 <iframe>
或 <script>
。示例包括 <img>
、<audio>
、<video>
、CSS 加载的 Web 字体和 WebGL 纹理。这些都通过 HTTP 请求加载,并且如前所述,这些 HTTP 请求将包括先前由其他站点设置的任何 Cookie、请求用户的 IP 地址以及当前页面的 URL 作为引荐来源网址。历史上,所有第三方请求默认都包含此数据,尽管各种浏览器都在努力减少或隔离传递给第三方的数据,详见后面的“了解第三方浏览器保护”。
嵌入跨站 iframe
通过 <iframe>
嵌入到您页面中的完整文档除了 Cookie、IP 地址和引荐来源网址这三要素外,还可以请求对浏览器 API 的额外访问权限。 <iframe>
页面可以访问哪些 API 以及它们如何请求访问权限是特定于浏览器的,并且目前正在发生变化:有关当前限制或监控嵌入式文档中 API 访问权限的努力,请参阅下面的“权限策略”。
执行跨站 JavaScript
包含 <script>
元素会在您页面的顶层上下文中加载并运行跨站 JavaScript。这意味着运行的脚本可以完全访问您自己的第一方脚本所做的任何事情。浏览器权限仍然管理此数据,因此请求用户的位置(例如)仍然需要用户同意。但是,页面中存在的或作为 JavaScript 变量可用的任何信息都可以被此类脚本读取,这不仅包括作为请求一部分传递给第三方的 Cookie,还包括仅供您的网站使用的 Cookie。同样,加载到您页面上的第三方脚本可以发出与您自己的代码相同的所有 HTTP 请求,这意味着它可以向您的后端 API 发出 fetch()
请求以获取数据。
在您的依赖项中包含第三方库
如前所述,您的服务器端代码也可能包含第三方依赖项,并且这些依赖项在其功能方面与您自己的代码没有区别;您从 GitHub 存储库或您的编程语言库(npm、PyPI、composer 等)中包含的代码可以读取与您的其他代码相同的所有数据。
了解您的第三方
因此,这需要您了解您的第三方供应商列表,以及他们的隐私、数据收集以及用户体验立场和政策。然后,这种理解成为您一系列权衡的一部分:该服务的有用性和重要性,与他们对您的用户的侵入性、不便性或令人不安的需求之间的权衡。第三方内容通过减轻您作为网站所有者的繁重工作并允许您专注于您的核心竞争力来提供价值;因此,权衡取舍并牺牲一些用户舒适度和隐私以获得更好的用户体验是有价值的。重要的是不要将用户体验与开发人员体验混淆,尽管如此:“我们的开发团队更容易构建服务”对用户来说并不是一个引人入胜的故事。
您如何获得这种理解就是审核过程。
审核您的第三方
了解第三方在做什么就是审核过程。您可以从技术和非技术两个方面进行此操作,并且可以针对单个第三方和您的整个集合进行此操作。
运行非技术审核
第一步是非技术性的:阅读您的供应商的隐私政策。如果您包含任何第三方资源,请查看隐私政策。它们将很长且充满法律文本,并且某些文档可能会使用早期模块中特别警告的一些方法,例如过于笼统的声明,并且没有任何关于如何或何时删除收集的数据的指示。重要的是要认识到,从用户的角度来看,在您的网站上收集的所有数据,包括由第三方收集的数据,都将受这些隐私政策的约束。即使您做的一切都正确,当您对您的目标保持透明并超出用户对数据隐私和敏感性的期望时,用户也可能会让您对您选择的第三方所做的任何事情负责。如果他们的隐私政策中有任何您不希望在您自己的政策中说明的内容,因为它会降低用户的信任度,那么请考虑是否有其他供应商。
这可以与稍后讨论的技术审核一起使用,因为它们彼此告知。您应该出于业务原因(例如广告网络或嵌入式内容)了解您正在合并的第三方资源,因为会存在业务关系。这是一个启动非技术审核的好地方。技术审核也可能识别出第三方,尤其是那些出于技术而非业务原因(外部组件、分析、实用程序库)包含的第三方,并且该列表可以与以业务为中心的第三方列表合并。这里的目标是让您作为网站所有者感觉您了解您添加到网站的第三方正在做什么,并让您作为企业能够向您的法律顾问提供此第三方清单,以确保您履行任何要求的义务。
运行技术审核
对于技术审核,重要的是在网站中就地使用资源;也就是说,不要在测试工具中加载依赖项并以这种方式检查它。确保您看到您的依赖项如何在您的实际网站中作为公共互联网上部署的一部分运行,而不是在测试或开发模式下运行。以新用户的身份查看您自己的网站非常有启发意义。在全新的干净配置文件中打开浏览器,以便您未登录并且没有存储的协议,然后尝试访问您的网站。
如果您提供用户帐户,请在您自己的网站上注册一个新帐户。您的设计团队将从 UX 角度协调此新用户获取过程,但从隐私角度来看,它可以很有启发意义。不要简单地单击“接受”条款和条件、Cookie 警告或隐私政策;给自己设定任务,在不泄露任何个人信息或不使用任何跟踪 Cookie 的情况下使用您自己的服务,看看您是否可以做到以及做到这一点有多难。查看浏览器开发者工具以查看正在访问哪些站点以及哪些数据传递到这些站点也很有帮助。开发者工具提供单独的 HTTP 请求列表(通常在名为“网络”的部分中),您可以从此处看到按类型分组的请求(HTML、CSS、图片、字体、JavaScript、JavaScript 发起的请求)。还可以添加一个新列以显示每个请求的域,这将演示联系了多少不同的位置,并且可能有一个“第三方请求”复选框来仅显示第三方。(使用 Content-Security-Policy
报告来执行持续审核也很有用,有关更多信息,请继续阅读。)
Simon Hearne 的“请求地图生成器”工具也可以帮助您全面了解公开可用的页面发出的所有子请求。
这也是您可以包括作为非技术审核一部分识别的以业务为中心的第三方(即:您为了使用其资源而与之建立财务关系的公司列表)的点。这里的目标是将您认为正在使用的第三方列表(来自财务和法律记录)与您实际使用的列表(通过查看您的网站发出的第三方 HTTP 请求)进行匹配。您应该能够为每个业务第三方识别出哪些技术出站请求被发出。如果您无法在技术审核中识别出由业务关系识别的第三方的请求,那么重要的是要弄清楚原因并让它指导您的测试:也许该第三方资源仅在特定国家/地区或特定设备类型上或针对登录用户加载。这将扩大您的网站区域列表以进行审核,并确保您看到所有出站访问。(或者可能会识别出您正在付费但未使用的第三方资源,这总是会让财务部门感到高兴。)
一旦您将请求列表缩小到您希望成为审核一部分的第三方,单击单个请求将显示其所有详细信息,特别是哪些数据已传递给该请求。也很常见的是,您代码启动的第三方请求然后继续启动许多其他第三方请求。这些额外的第三方也被“导入”到您自己的隐私政策中。这项任务很费力但很有价值,并且通常可以插入到现有分析中;您的前端开发团队应该已经出于性能原因审核请求(可能借助 WebPageTest 或 Lighthouse 等现有工具),并将数据和隐私审核纳入该过程可以使其更容易。

操作
打开一个具有全新用户配置文件的浏览器,以便您未登录且没有存储的协议;然后打开浏览器开发者工具“网络”面板,查看所有出站请求。添加一个新列以显示每个请求的域,并选中“第三方请求”复选框以仅显示第三方(如果存在)。然后
- 访问您的网站。
- 如果您提供用户帐户,请注册一个新帐户。
- 尝试删除您创建的帐户。
- 在网站上执行一两个正常操作(具体是什么取决于您的网站的功能,但选择大多数用户执行的常见操作)。
- 执行一两个您知道特别涉及第三方依赖项的操作。这些可能包括将内容分享到社交媒体、开始结帐流程或嵌入来自其他网站的内容。
在执行这些任务中的每一个时,通过查看如上所述的“网络”面板,记录从非您的域请求的资源。这些是您的一些第三方。执行此操作的一个好方法是使用浏览器网络工具捕获 HAR 文件中的网络请求日志。
HAR 文件和捕获
HAR 文件是页面发出的所有网络请求的标准化 JSON 格式。要获取特定页面的 HAR 文件,请在
Chrome 浏览器中
打开浏览器 DevTools(菜单 > 更多工具 > 开发者工具),转到“网络”面板,加载(或刷新)页面,然后在右上角靠近“无节流”下拉菜单的位置选择向下箭头保存符号。

Firefox 浏览器中
打开浏览器开发者工具(菜单 > 更多工具 > Web 开发者工具),转到“网络”面板,加载(或刷新)页面,然后在节流下拉菜单旁边的右上角选择齿轮符号。从其菜单中,选择 另存为 HAR**。

Safari 浏览器中
打开浏览器开发者工具(菜单 > 开发 > 显示 Web Inspector;如果您没有“开发”菜单,请从菜单 > Safari 浏览器 > 偏好设置 > 高级 > 在菜单栏中显示“开发”菜单启用它),转到“网络”面板,加载(或刷新)页面,然后在右上角(“保留日志”的右侧)选择导出(您可能需要放大窗口)。

为了获得更详细的信息,您还可以记录传递给第三方的内容(在“请求”部分中),尽管这些数据通常是混淆的,并且难以解释。
集成第三方时的最佳实践
您可以设置自己的策略来决定您的网站使用哪些第三方:根据广告提供商的实践、他们的 Cookie 同意弹出窗口的烦人程度或侵入性程度,或者您是否希望在您的网站上使用社交媒体按钮、电子邮件中的跟踪链接或 utm_campaign 链接来跟踪您在 Google Analytics 中的推文,来更改您使用的广告提供商。在开发网站时,需要考虑的一个方面是您的分析服务的隐私和安全态势。一些分析服务明确以保护隐私为卖点。通常,也有一些方法可以使用第三方脚本本身来增加隐私保护:您不是第一个寻求改善用户隐私并保护他们免受第三方数据收集的团队,并且可能已经有解决方案。最后,许多第三方提供商现在比过去更关注数据收集问题,并且通常可以添加一些功能或参数来启用更注重用户保护的模式。以下是一些示例。
添加社交媒体分享按钮时
考虑直接嵌入 HTML 按钮:网站 https://sharingbuttons.io/ 提供了一些设计精良的示例。或者您可以添加纯 HTML 链接。这里的权衡是您会失去“分享计数”统计数据以及在 Facebook 分析中对客户进行分类的能力。这是使用第三方提供商和接收较少分析数据之间权衡的一个例子。
更一般地说,当您嵌入来自第三方的某种交互式小部件时,通常可以改为提供指向该第三方的链接。这确实意味着您的网站没有内联体验,但它将与第三方共享数据的决定从您转移到您的用户,用户可以选择是否互动。
例如,您可以添加 Twitter 和 Facebook 的链接,以分享您在 mysite.example.com 上的服务,如下所示
<a href="https://facebook.com/sharer/sharer.php?u=https%3A%2F%2Fmysite.example.com"
rel="noopener" aria-label="Share on Facebook" target="_blank" >Share on Facebook</a>
<a href="https://twitter.com/intent/tweet/?text=My%20cool%20service!&url=https%3A%2F%2Fmysite.example.com"
rel="noopener" aria-label="Share on Twitter" target="_blank">Share on Twitter</a>
请注意,Facebook 允许指定要分享的 URL,而 Twitter 允许指定 URL 和一些文本。
嵌入视频时
当您从视频托管网站嵌入视频时,请在嵌入代码中查找保护隐私的选项。例如,对于 YouTube,将嵌入 URL 中的 youtube.com
替换为 www.youtube-nocookie.com
,以避免在查看嵌入页面的用户设备上放置跟踪 Cookie。您还可以在从 YouTube 本身生成“分享/嵌入”链接时选中“启用增强隐私模式”。这是使用第三方提供的更注重用户保护的模式的一个很好的例子。(https://support.google.com/youtube/answer/171780 更详细地描述了这一点,以及 YouTube 的其他特定嵌入选项。)
其他视频网站在这方面提供的选项较少:例如,在撰写本文时,TikTok 尚无在不进行跟踪的情况下嵌入视频的方法。可以自己托管视频(这是使用替代方案),但这可能需要做更多的工作,尤其是在支持多种设备的情况下。
与前面讨论的交互式小部件一样,通常可以用指向提供网站的链接替换嵌入视频。这交互性较差,因为视频不会内联播放,但它将是否观看的选择权留给了用户。这可以用作“外观模式”的一个例子,外观模式是指用需要用户操作才能触发的内容动态替换交互式内容。嵌入的 TikTok 视频可以用指向 TikTok 视频页面的纯链接替换,但稍微多做一些工作,就可以检索并显示视频的缩略图,并将其作为链接。即使选定的视频提供商不支持轻松嵌入不跟踪的视频的方法,许多视频托管商也支持 oEmbed,这是一种 API,当给定视频或嵌入内容的链接时,它将返回其程序化详细信息,包括缩略图和标题。TikTok 支持 oEmbed(详见 https://developers.tiktok.com/doc/embed-videos),这意味着您可以(手动或以编程方式)将 TikTok 视频的链接 https://www.tiktok.com/@scout2015/video/6718335390845095173
转换为关于该视频的 JSON 元数据,网址为 https://www.tiktok.com/oembed?url=https://www.tiktok.com/@scout2015/video/6718335390845095173
,因此检索缩略图以显示。例如,WordPress 经常使用它来请求嵌入内容的 oEmbed 信息。您可以以编程方式使用它来显示一个“外观”,看起来是交互式的,并在用户选择单击它时切换到嵌入或链接到交互式视频。
嵌入分析脚本时
分析旨在收集有关用户的信息,以便对其进行分析:这就是它的用途。分析系统本质上是收集和显示有关访问和用户数据的服务,为了易于实施,这通常在第三方服务器(例如 Google Analytics)上完成。也有自托管的分析系统,例如 https://matomo.org/,尽管这比使用第三方解决方案要付出更多的工作。但是,在您自己的基础设施上运行这样的系统确实有助于您减少数据收集,因为它不会离开您自己的生态系统。另一方面,管理这些数据、删除数据以及为其设置策略将成为您的责任。对跨站点跟踪的大部分担忧来自于它是在秘密和隐蔽地进行的,还是作为使用一项不必包含数据收集的服务的副作用。分析软件被公开设计为收集数据,以便告知网站所有者有关其用户的信息。
从历史上看,一直有一种方法是尽可能多地收集关于一切的数据,就像一张巨大的渔网,然后在以后分析它以寻找有趣的模式。这种心态在很大程度上造成了人们对数据收集的不安和疑虑,这在本课程的第一部分中已经讨论过。现在,许多网站首先确定要提出的问题,然后收集特定的、有限的数据来回答这些问题。
如果您的网站和其他网站都使用了某个第三方服务,并且它的工作原理是将他们的 JavaScript 包含到您的网站中,并为每个用户设置 Cookie,那么重要的是要考虑到他们可能会进行不必要的跨站点识别;也就是说,跨站点跟踪您的用户。有些可能会这样做,有些可能不会,但这里的隐私保护立场是假设这样的第三方服务实际上正在进行跨站点跟踪,除非您有充分的理由认为或知道情况并非如此。这本身并不是避免使用此类服务的原因,但它是您在评估使用它们的权衡时需要考虑的事情。
分析中的权衡曾经只是选择是否使用它:收集所有数据并以隐私为代价换取洞察和规划,或者完全放弃洞察。然而,现在情况已不再如此,并且现在通常可以在这两种极端之间找到一个中间地带。检查您的分析提供商的配置选项,以限制收集的数据并减少其存储量和持续时间。由于您拥有前面描述的技术审核记录,您可以重新运行该审核的相关部分,以确认更改这些配置是否确实减少了数据收集量。如果您正在现有网站上进行此转换,那么这可以为您提供一些可量化的指标,可以为您的用户编写相关内容。例如,Google Analytics 有许多 选择加入(因此默认关闭) 隐私功能,其中许多功能可能有助于遵守当地的数据保护法律。设置 Google Analytics 时可以考虑的一些选项包括将收集数据的保留期限(管理 > 跟踪信息 > 数据保留)设置为低于 26 个月的默认值,以及启用一些更技术性的解决方案,例如部分 IP 匿名化(详见 https://support.google.com/analytics/answer/9019185)。
以保护隐私的方式使用第三方
到目前为止,我们已经讨论了如何在应用程序的设计阶段(当您计划该应用程序将做什么时)保护您的用户免受第三方的侵害。决定完全不使用特定的第三方是此计划的一部分,而审核您的用途也属于此类别:这关系到制定关于您的隐私立场的决策。但是,这些决策本质上不是很精细;选择使用特定的第三方或选择不使用并不是一个细致入微的决策。更有可能的是,您会想要介于两者之间的东西:需要或计划使用特定的第三方产品,但减轻任何侵犯隐私的倾向(无论是故意的还是偶然的)。这是在“构建时”保护用户的任务:添加安全措施以减少您未预料到的危害。所有这些都是新的 HTTP 标头,您可以在提供页面时提供这些标头,这些标头将提示或命令用户代理采取某些隐私或安全立场。
Referrer-Policy
操作
设置 strict-origin-when-cross-origin
或 noreferrer
策略,以防止其他网站在您链接到它们时或当它们作为子资源被页面加载时接收到 Referer 标头
index.html:
<meta name="referrer" content="strict-origin-when-cross-origin" />
或者服务器端,例如在 Express 中
const helmet = require('helmet');
app.use(helmet.referrerPolicy({policy: 'strict-origin-when-cross-origin'}));
如有必要,在特定元素或请求上设置更宽松的策略。
为什么这能保护用户隐私
默认情况下,浏览器发出的每个 HTTP 请求都会传递一个 Referer
标头,其中包含发起请求的页面的 URL,无论是链接、嵌入的图像还是脚本。这可能是一个隐私问题,因为 URL 可能包含私人信息,并且这些 URL 可供第三方使用会将私人信息传递给他们。Web.dev 列出了一些包含私人数据的 URL 示例——知道用户来自 https://social.example.com/user/me@example.com
会告诉您该用户是谁,这绝对是一种泄露。但即使是不暴露私人信息本身的 URL 也会暴露这个特定用户(如果您知道他们是谁,如果他们已登录)来自另一个网站,因此会泄露该用户访问过该另一个网站。这本身就是暴露您可能不应该知道的关于用户浏览历史记录的信息。
提供 Referrer-Policy
标头(拼写正确!)允许您更改此行为,以便传递部分或全部引用 URL。MDN 列出了完整详细信息,但大多数浏览器现在默认采用 strict-origin-when-cross-origin
的假定值,这意味着引用 URL 现在仅作为来源传递给第三方(https://webdev.ac.cn
而不是 https://webdev.ac.cn/learn/privacy
)。这是一种有用的隐私保护,无需您做任何事情。但是您可以通过指定 Referrer-Policy: same-origin
来进一步加强这一点,以避免向第三方传递任何引用信息(或 Referrer-Policy: no-referrer
以避免向包括您自己的来源在内的任何人传递)。(这是隐私与实用性平衡的一个很好的例子;新的默认值比以前更注重隐私保护,但它仍然向您选择的第三方(例如您的分析提供商)提供高级别信息。)
显式指定此标头也很有用 因为这样您就可以确切地知道策略是什么,而不是依赖浏览器默认值。如果您无法设置标头,则可以使用 <head>
中的 meta 元素为整个 HTML 页面设置引用策略:<meta name="referrer" content="same-origin">
;如果担心特定的第三方,也可以在单个元素(例如 <script>
、<a>
或 <iframe>
)上设置 referrerpolicy
属性:<script src="https://thirdparty.example.com/data.js" referrerpolicy="no-referrer">
Content-Security-Policy
Content-Security-Policy
标头,通常称为“CSP”,规定了可以从哪里加载外部资源。它主要用于安全目的,通过防止跨站点脚本攻击和脚本注入,但当与您的定期审核一起使用时,它还可以限制您选择的第三方可以将数据传递到哪里。
这可能不是一个很好的用户体验;如果您的第三方脚本之一开始从不在您的列表中的来源加载依赖项,则该请求将被阻止,脚本将失败,并且您的应用程序可能会随之失败(或至少降级为 JavaScript 失败的回退版本)。当 CSP 用于安全目的时,这是有用的,这是它的正常用途:防止跨站点脚本问题(为此,请使用 严格的 CSP)。一旦您知道您的页面使用的所有内联脚本,您就可以列出它们,计算哈希值或为每个脚本添加一个随机值(称为“nonce”),然后将哈希列表添加到您的内容安全策略中。这将阻止加载任何不在列表中的脚本。这需要烘焙到网站的生产过程中:页面中的脚本需要包含 nonce 或在构建过程中计算哈希值。有关所有详细信息,请参阅 关于 strict-csp 的文章。
幸运的是,浏览器支持一个相关的标头 Content-Security-Policy-Report-Only
。如果提供了此标头,则违反所提供策略的请求不会被阻止,但 JSON 报告将被发送到提供的 URL。这样的标头可能如下所示:Content-Security-Policy-Report-Only: script-src 3p.example.com; report-uri https://example.com/report/
,如果浏览器从 3p.example.com
以外的任何地方加载脚本,则该请求将成功,但报告将发送到提供的 report-uri
。通常,这用于在实施策略之前对其进行实验,但这里的一个有用的想法是将此用作进行“持续审核”的一种方式。除了您之前描述的定期审核之外,您还可以打开 CSP 报告,以查看是否出现任何意外的域,这可能意味着您的第三方资源正在加载它们自己的第三方资源,而您需要考虑和评估这些资源。(当然,这也可能是跨站点脚本利用漏洞已经溜过您的安全边界的迹象,了解这一点也很重要!)
Content-Security-Policy
是一个复杂且繁琐的 API。这是已知的,并且正在努力构建“下一代”CSP,它将实现相同的目标,但使用起来不会那么复杂。这尚未准备就绪,但如果您想了解它的发展方向(或参与并帮助其设计!),请查看 https://github.com/WICG/csp-next 了解详细信息。
操作
将此 HTTP 标头添加到提供的页面:Content-Security-Policy-Report-Only: default-src 'self'; report-uri https://a-url-you-control
。当 JSON 发布到该 URL 时,存储它。查看存储的数据以获取您的网站在其他人访问时请求的第三方域的集合。更新 Content-Security-Policy-Report-Only
标头以列出您期望的域,以便查看该列表何时更改
Content-Security-Policy-Report-Only: default-src 'self' https://expected1.example.com https://expected2.example.com ; report-uri https://a-url-you-control
为什么
这构成了您的技术审核的一部分,并且是持续进行的。您执行的初始技术审核将为您提供一份第三方列表,您的网站会与这些第三方共享或传递用户数据。然后,此标头将导致页面请求报告现在正在联系哪些第三方,您可以跟踪随时间的变化。这不仅会提醒您现有第三方所做的更改,还会标记未添加到技术审核中的新添加的第三方。重要的是更新标头以停止报告您期望的域,但同样重要的是不时重复手动技术审核(因为 Content-Security-Policy
方法不标记传递了什么数据,仅标记发出了请求。)
请注意,不需要每次或每个页面都添加到提供的页面。调整接收标头的页面响应数量,以便您收到具有代表性的报告样本,而不会数量过多。
Permissions policy
Permissions-Policy
标头(以 Feature-Policy
的名称引入)在概念上与 Content-Security-Policy
类似,但它限制对强大的浏览器功能的访问。例如,可以限制使用设备硬件(如加速计、摄像头或 USB 设备),或限制非硬件功能(如全屏权限或使用同步 XMLHTTPRequest
)。这些限制可以应用于顶级页面(以避免加载的脚本尝试使用这些功能)或通过 iframe 加载的子框架页面。这种 API 使用限制实际上与浏览器 指纹识别 无关;它旨在禁止第三方进行侵入性操作(例如使用强大的 API、弹出权限窗口等)。Target Privacy Threat Model 将其定义为 “入侵”。
Permissions-Policy
标头指定为(功能,允许的来源)对的列表,因此
Permissions-Policy: geolocation=(self "https://example.com"), camera=(), fullscreen=*
此示例允许此页面(“self”)和来自来源 example.com
的 <iframe>
使用 JavaScript 中的 navigator.geolocation
API;它允许此页面和所有子框架使用全屏 API,并且禁止任何页面(包括此页面)使用摄像头读取视频信息。此处有更多详细信息和 潜在示例列表。
Permissions-Policy 标头处理的功能列表很长,并且可能正在不断变化。当前列表维护在 https://github.com/w3c/webappsec-permissions-policy/blob/main/features.md。
操作
支持 Permissions-Policy
的浏览器默认情况下不允许在子框架中使用强大的功能,您必须采取行动才能启用它们!这种方法默认是私有的。如果您发现您网站上的子框架需要这些权限,您可以有选择地添加它们。但是,默认情况下,没有权限策略应用于主页面,因此主页面加载的脚本(包括第三方脚本)不受限制,可以尝试使用这些功能。因此,默认情况下对所有页面应用限制性 Permissions-Policy
,然后逐渐添加回您的页面需要的功能是很有用的。
Permissions-Policy
影响的强大功能示例包括请求用户的位置、访问传感器(包括加速计、陀螺仪和磁力计)、全屏权限以及请求访问用户的摄像头和麦克风。上面链接了(正在变化的)完整功能列表。
不幸的是,默认情况下阻止所有功能,然后有选择地重新允许它们需要列出标头中的所有功能,这可能会让人感觉相当笨拙。尽管如此,这样的 Permissions-Policy
标头仍然是一个好的开始。permissionspolicy.com/ 有一个方便的、可点击的生成器来创建这样的标头:使用它来创建一个禁用所有功能的标头会产生以下结果
Permissions-Policy: accelerometer=(), ambient-light-sensor=(), autoplay=(), battery=(), camera=(), cross-origin-isolated=(),
display-capture=(), document-domain=(), encrypted-media=(), execution-while-not-rendered=(), execution-while-out-of-viewport=(),
fullscreen=(), geolocation=(), gyroscope=(), keyboard-map=(), magnetometer=(), microphone=(), midi=(), navigation-override=(),
payment=(), picture-in-picture=(), publickey-credentials-get=(), screen-wake-lock=(), sync-xhr=(), usb=(), web-share=(), xr-spatial-tracking=()
了解 Web 浏览器中的内置隐私功能
除了“构建时”和“设计时”保护之外,还有在“运行时”发生的隐私保护:即,浏览器本身实施的隐私功能,以保护用户。这些不是您可以作为网站开发人员直接控制或利用的功能——它们是产品功能——但您应该意识到这些功能,因为您的网站可能会受到浏览器中的这些产品决策的影响。举一个例子来说明这些浏览器保护可能会如何影响您的网站,如果您有客户端 JavaScript,它会等待第三方依赖项加载后再继续进行页面设置,而该第三方依赖项根本没有加载,那么您的页面设置可能永远无法完成,因此用户看到的是一个半加载的页面。
它们包括 Safari 中的 Intelligent Tracking Prevention(以及底层的 WebKit 引擎)和 Firefox 中的 Enhanced Tracking Protection(及其引擎 Gecko)。所有这些都使第三方难以构建用户详细的个人资料。
浏览器关于隐私功能的方法经常变化,保持最新非常重要;以下保护列表在撰写本文时是正确的。浏览器也可能实施其他保护措施;这些列表并非详尽无遗。请参阅 关于最佳实践的模块,了解如何在此处及时了解变化,并务必使用即将推出的浏览器版本进行测试,以了解可能影响您项目的变化。请记住,隐身/隐私浏览模式有时会实施与浏览器默认设置不同的设置(例如,在这种模式下,第三方 Cookie 可能会默认被阻止)。因此,如果在隐身模式下进行测试,可能并不总是能反映大多数用户在不使用隐私浏览时的典型浏览体验。另请记住,在各种情况下阻止 Cookie 可能意味着其他存储解决方案(例如 window.localStorage
)也会被阻止,而不仅仅是 Cookie。
Chrome 浏览器中
- 第三方 Cookie 计划在未来被阻止。截至撰写本文时,它们默认未被阻止(但用户可以启用):https://support.google.com/chrome/answer/95647 解释了详细信息。
- Chrome 的隐私功能,特别是 Chrome 中与 Google 和第三方服务通信的功能,在 privacysandbox.com/ 中进行了描述。
Edge
- 第三方 Cookie 默认情况下未被阻止(但用户可以启用)。
- Edge 的 Tracking Prevention 功能阻止来自未访问站点的跟踪器,并且默认情况下会阻止已知的有害跟踪器。
Firefox 浏览器中
- 第三方 Cookie 默认情况下未被阻止(但用户可以启用)。
- Firefox 的 Enhanced Tracking Protection 默认阻止跟踪 Cookie、指纹识别脚本、加密货币挖矿脚本和已知跟踪器。(https://support.mozilla.org/kb/trackers-and-scripts-firefox-blocks-enhanced-track 提供了一些更多详细信息)。
- 第三方 Cookie 是站点受限的,因此每个站点本质上都有一个单独的 Cookie 罐,并且无法跨站点关联(Mozilla 称之为“Total Cookie Protection”。
要深入了解可能被阻止的内容并帮助调试问题,请单击地址栏中的盾牌图标或访问 Firefox 中的 about:protections
(在桌面上)。
Safari 浏览器中
- 第三方 Cookie 默认情况下被阻止。
- 作为其 Intelligent Tracking Prevention 功能的一部分,Safari 将传递给其他页面的引用者减少为顶级站点,而不是特定页面:(
https://something.example.com
,而不是https://something.example.com/this/specific/page
)。 - 浏览器
localStorage
数据在七天后被删除。
(https://webkit.org/blog/10218/full-third-party-cookie-blocking-and-more/ 总结了这些功能。)
要深入了解可能被阻止的内容并帮助调试问题,请在 Safari 的开发者菜单(在桌面上)中启用“Intelligent Tracking Prevention Debug Mode”。(详见 https://webkit.org/blog/9521/intelligent-tracking-prevention-2-3/。)
API 提案
为什么我们需要新的 API?
虽然浏览器产品中新的保护隐私的功能和策略有助于保护用户隐私,但它们也带来了一些挑战。许多 Web 技术虽然是为其他目的而设计和使用的,但也可以用于跨站点跟踪。例如,我们每天使用的许多身份联合系统都依赖于第三方 Cookie。发布商今天赖以获得收入的许多广告解决方案都建立在第三方 Cookie 之上。许多欺诈检测解决方案依赖于指纹识别。当第三方 Cookie 和指纹识别消失时,这些用例会发生什么?
浏览器很难区分用例,也很难可靠地区分侵犯隐私的用途和其他用途。这就是为什么大多数主要浏览器都阻止了第三方 Cookie 和指纹识别或打算这样做,以保护用户隐私。
需要一种新的方法:随着第三方 Cookie 被逐步淘汰和指纹识别被缓解,开发人员需要专门构建的 API,以满足用例(这些用例并没有消失),但这些 API 的设计方式要保护隐私。目标是设计和构建无法用于跨站点跟踪的 API。与上一节中描述的浏览器功能不同,这些技术渴望成为跨浏览器 API。
API 提案示例
以下列表并非详尽无遗——它只是对正在讨论的一些内容的简要介绍。
旨在取代构建在第三方 Cookie 之上的技术的 API 提案示例
- 身份用例:FedCM
- 广告用例:Private Click Measurement、Interoperable Private Attribution、Attribution Reporting、Topics、FLEDGE、PARAKEET。
旨在取代构建在被动跟踪之上的技术的 API 提案示例
- 欺诈检测用例:Trust Tokens。
其他 API 可以在未来没有第三方 Cookie 的情况下构建在其之上的提案示例
此外,另一种类型的 API 提案正在涌现,试图解决迄今为止浏览器特定的隐蔽跟踪缓解措施。一个例子是 Privacy Budget。在这些各种用例中,最初由 Chrome 提出的 API 统称为 Privacy Sandbox。
Global-Privacy-Control 是一个标头,旨在向网站传达用户希望任何收集到的个人数据都不与其他网站共享。它的意图与已停止使用的 Do Not Track 类似。
API 提案的状态
这些 API 提案中的大多数尚未部署,或者仅在标志后或在有限的环境中部署以进行实验。
这个公共孵化阶段非常重要:浏览器供应商和开发人员收集关于这些 API 是否有用以及它们是否真正实现其设计目的的讨论和经验。开发人员、浏览器供应商和其他生态系统参与者使用此阶段来迭代 API 的设计。
目前,了解最新提出的新 API 的最佳场所是 Privacy Group 在 Github 上的提案列表。
您需要使用这些 API 吗?
如果您的产品直接构建在第三方 Cookie 或指纹识别等技术之上,您应该参与这些新的 API,进行实验,并将您自己的经验贡献给讨论和 API 设计。在所有其他情况下,您不一定需要了解撰写本文时这些新 API 的所有详细信息,但了解即将发生的事情是很好的。