category
目录
- 动机
- CHIPS:选择分区Cookie
- 现有技术
- 默认情况下对所有第三方cookie进行分区
- 使用存储访问API进行选择
- 现有技术
- 非目标
- 关键场景
- 第三方店铺查找服务
- 第三方客服聊天嵌入
- CDN负载平衡
- 用例的其他示例
- 设计原则
- 选择分区cookie
- 仅通过安全协议发送
- 避免占用大量内存
- 详细设计
- 分区模型
- 选择加入cookie属性
- 使用分区的Set Cookie
- 将分区cookie附加到请求
- 示例用法
- 第三方定位器服务
- 第三方客户支持小部件
- CDN负载平衡
- 如何执行设计原则
- 安全属性
- HttpOnly属性
- SameSite属性
- 限制第三方在单个分区中可以使用的cookie数量
- 清除分区的cookie
- Cookie Store API
- 存储访问API
- 处理较旧或不兼容的客户端
- 内存影响
- 服务人员
- 浏览器扩展
- 扩展页
- 背景背景
- 第一方CHIPS
- 安全和隐私注意事项
- CHIPS的替代设计
- 限制分区中cookie的数量
- 应用每个域180个cookie的限制
- DNS CNAME
- 参考和确认
- 鸣谢
- 工具书类
动机
为了增加网络隐私,浏览器供应商正在计划或已经对跨站点跟踪进行限制。这包括逐步取消对第三方cookie的支持,即向顶级文档网站以外的网站发送请求的cookie,因为此类cookie使服务器能够跟踪用户在不同顶级网站上的行为。
在CHIPS之前,当第三方在一个网站上设置cookie时。。。
…则该网站可以访问不同顶级网站上的同一cookie。
在cookie之前:浏览器访问green.com,它有一个嵌入的red.com框架,可以设置cookie。当浏览器导航到blue.com时,red.com框架可以访问green.com上的cookie集。
尽管第三方cookie可以使第三方网站跟踪不同顶级网站上的用户行为,但目前网络上存在一些cookie用例,其中跨域子资源需要一些会话或持久状态的概念,这些概念的范围仅限于用户在单个顶级网站上活动。
CHIPS:选择分区Cookie
为了满足使用情况,我们建议引入分区Cookie,也称为CHIPS(具有独立分区状态的Cookie)。第三方可以通过将其跨站点cookie设置为Partitioned属性来选择使用CHIPS。此属性将向用户代理指示,这些跨站点cookie应仅在创建cookie的同一顶级站点中可用。
根据这一提议,当用户访问green.com,并且来自red.com的嵌入内容设置了一个cookie以响应跨站点请求时,用户代理只会在顶级站点为green.com时发送该cookie。当他们访问新站点blue.com时,嵌入的red.com框架将不会收到red.com嵌入green.com时设置的cookie。
CHIPS之后,第三方的cookie罐由顶级网站进行分区。
因此,第三方将无法访问他们在另一个顶级网站上设置的cookie。
饼干之后:浏览器访问green.com,该网站嵌入了一个设置饼干的red.com框架。当用户访问blue.com时,red.com框架无法访问green.com上的cookie集,因为它是不同的顶级网站。
注意:Firefox最近引入了默认情况下对所有第三方cookie进行分区,作为ETP严格模式下的兼容性措施,Safari在之前版本的ITP中短暂启用(随后回滚)了这一功能。有关他们方法的更多详细信息,请在默认情况下对所有第三方cookie进行分区中进行讨论。
现有技术
默认情况下对所有第三方cookie进行分区
Firefox宣布,默认情况下,他们将所有第三方cookie划分为ETP严格模式,即所有跨站点cookie都按顶级站点划分,无需任何选择。Safari之前曾尝试基于启发式方法对cookie进行分区,但最终选择完全阻止它们,原因之一是开发者感到困惑。
我们认为,在没有第三方选择加入的情况下,不应该对cookie进行分区,因为第三方构建其现有服务器时期望得到未分区的第三方cookie。这可能会导致混乱和意外的错误(1、2、3、4)。
默认情况下,对于浏览器开发人员来说,分区也有更多的实现复杂性,因为他们需要考虑对cookie jar进行分区将如何影响浏览器中与cookie交互的任何部分。支持选择加入cookie分区,同时逐步将网络从全局范围的第三方cookie中移除,这将有助于简化浏览器的过渡。
还有国家扩散的问题。今天,网络上有一些第三方起源,在许多分区中都很普遍。如果我们默认情况下对cookie jar进行分区,并且不包括每个cookie jar分区大小的新上限,那么设备存储限制将更快地耗尽。
使用存储访问API进行选择
在撰写本文时,有一项关于选择分区cookie的建议正在讨论中,但用户将选择使用Storage Access API向第三方提供分区cookie罐,而不是使用cookie属性。
非目标
- 本文档不描述顶级网站与自己的cookie交互方式的任何更改。对于顶级网站所有者,大多数分区cookie用例都是通过使用SameSite=Lax/Strict来覆盖的。然而,在不常见的情况下,CHIPS可能对顶级网站所有者有用。有关更多信息,请参阅下面的第一方CHIPS部分。
- 本文档不描述在同一第一组织拥有的不同域之间共享的第三方cookie的替代品。对于此用例,请考虑使用第一方集。
- 本文档也没有描述对cookie以外的任何其他类型的浏览器存储进行分区(例如HTTP缓存、LocalStorage、服务工作者等)。
- 本文档未说明如何删除未分区的跨站点cookie(即第三方cookie)。本文档描述了一种选择加入跨站点cookie分区机制,该机制将在完全删除第三方cookie之前引入。其动机是在浏览器完全删除未分区的第三方cookie之前,为跨站点cookie用例提供一条明确的前进道路,这些跨站点cookie的使用范围为单个顶级上下文上的活动。
关键场景
以下是一些与跟踪无关的第三方cookie用例示例,我们希望通过CHIPS支持这些用例。我们首先描述了未分区的第三方cookie是如何满足特定用例的,然后我们描述了跨站点cookie按顶级站点分区时的理想最终状态。
第三方店铺查找服务
在阻止未分区的第三方cookie之前
假设shoes.com上的一个页面想向用户显示他们商店位置的地图,但他们没有资源来实现定位服务。相反,他们与第三方SaaS提供商embed.mass.com签订了合同,shoes.com嵌入了embed.mas.com拥有的框架,该框架提供了一个地图,用户可以使用该地图来选择他们喜欢的商店位置并查找方向。
当浏览器位于shoes.com上时,embed.mass.com拥有的嵌入式框架会设置一个cookie来存储用户的首选商店位置:
Set-Cookie: __Host-locationid=187; SameSite=None; Secure; HttpOnly; Path=/;
在随后访问shoes.com时,对embed.mass.com的第一个请求将包括以下标题:
Cookie: __Host-locationid=187;
这允许embed.mass.com知道用户对shoes.com的首选位置,该位置可用于服务器端渲染其地图,从而使最终用户看到更快的加载地图,从而记住他们的首选商店位置。然而,这个未分区的cookie也可以包括跨站点标识符,使embed.mass.com可以跟踪顶级站点的用户活动。
阻止未分区的第三方cookie后
在无法设置任何跨站点cookie的情况下,embed.mass.com等服务的一个替代方案是使用其他形式的浏览器存储(例如LocalStorage)。为了检测这些其他类型的客户端状态的存在,embed.mass.com必须等待加载JavaScript执行上下文,然后才能访问用户偏好:这会导致加载时间更长,用户体验更差。
我们的目标是,像embed.mass.com这样的网站能够在嵌入到shoes.com时设置cookie,该cookie只有在用户浏览器的顶级网站是shoes.com的情况下才会发送。如果用户导航到另一个顶级网站,则随后对embed.mas.com的请求将不包括顶级网站是shoes.com时所设置的cookie。这将使embed.mas.com.cn能够使用cookie存储用户偏好,而无需在用户的计算机上存储跨站点标识符。
第三方客服聊天嵌入
在阻止未分区的第三方cookie之前
以retail.com为例,它注意到用户在注册帐户和浏览网站的购买流程时遇到了问题。retail.com的所有者与第三方support.chat.com签订合同,在retail.com上嵌入聊天小工具,以帮助需要支持的用户。
当用户与support.chat.com的小部件交互时,他们会设置一个会话cookie来继续顶级页面导航之间的对话:
Set-Cookie: __Host-coversationid=a3e70; SameSite=None; Secure; HttpOnly; Path=/;
这样,当retail.com上加载新页面时,使用support.chat.com加载框架的请求将包括一个cookie,该cookie可以让support.chatcom知道该请求属于哪个会话:
Cookie: __Host-coversationid=a3e70;
但是,此cookie还为support.chat.com提供了一个跨站点标识符,他们可以使用该标识符来跟踪其他使用support.chat网站的用户。
阻止未分区的第三方cookie后
如果没有设置跨站点cookie的能力,support.chat.com可以依靠retail.com传递其第一方状态(或其衍生值)。然而,如果用户还没有创建帐户,并且支持小部件正在帮助他们注册,那么retail.com将没有身份的概念可以转发到support.chat.com。
support.chat.com还可以使用其他存储方法,如LocalStorage或IndexedDB。但是,与上面使用embed.map.com的示例一样,这些存储方法需要support.chat.com等待加载JavaScript上下文以访问其状态。
我们的目标是为support.chat.com等服务提供在第三方环境中设置cookie的能力。然而,只有当用户浏览设置cookie的同一顶级网站时,该cookie才可用。这使得support.chat.com可以在一个顶级网站内拥有会话概念,而无需提供跨网站跟踪机制。
CDN负载平衡
在阻止未分区的第三方cookie之前
以使用第三方CDN(static.CDN.com)托管其一些静态资产的网站example.com为例。static.cdn.com的网络使用负载平衡服务器,这些服务器使用cookie来存储计算结果,这是路由传入请求的最佳方式。
对于未分区的第三方Cookie,当用户第一次导航到example.com时,static.cdn.com将使用以下Set Cookie标头响应浏览器的第一个请求:
Set-Cookie: __Host-lb=a3e7; SameSite=None; Secure; HttpOnly; Path=/;
…其中cookie的值是static.cdn.com的负载均衡器可以用来引导请求的一些位字符串。随后对static.cdn.com的请求将包括以下Cookie标头:
Cookie: __Host-lb=a3e7;
以这种方式设置cookie的能力允许对static.cdn.com的请求具有较低的延迟,因为它们不需要计算如何将每个请求路由到服务器。这种改进的延迟为使用static.cdn.com提供静态内容的网站上的用户提供了更好的体验。
这种设计的问题是,当用户导航到另一个也使用static.cdn.com提供静态内容的顶级网站时,负载平衡cookie将在请求中发送到static.cdn.com.因此,static.cdn.com.cn也可以使用此cookie将用户在不同顶级网站上的会话绑定在一起。
阻止未分区的第三方cookie后
如果没有未分区的cookie,static.cdn.com就无法使用cookie在客户端存储负载平衡信息。这意味着他们必须计算每次用户ping服务器时路由请求的最佳方式,但这会增加延迟并导致用户沮丧。static.cdn.com可以使用其他存储机制来为其负载均衡器存储这些信息,但这意味着static.cdncom需要执行脚本才能访问这些信息。这意味着,如果example.com只是使用static.cdn.com来托管静态资产,并且不想将其JavaScript嵌入到其网站中,则用户将经历高延迟。
我们的目标是允许像static.cdn.com这样的第三方cdn能够为其负载平衡器使用cookie,但要按顶级网站对这些cookie进行分区。这意味着,如果static.cdn.com在example.com上的浏览器上设置了负载平衡cookie,则当浏览器导航到other.com时,对static.cdns.com的请求将不包括该cookie。
这意味着static.cdn.com将不得不为用户访问的每个顶级站点重新计算负载平衡cookie的值。然而,这比在第三方上下文中阻止所有cookie更可取,因为这样static.cdn.com每次都必须计算路由请求的最佳方式。对于static.cdn.com,分区cookie也比JavaScript存储更可取,因为在加载文档之前,存储中的任何数据都不可用。
用例的其他示例
上面未列出的分区cookie的其他一些用例示例如下:
- 使用Cookie提供访问控制内容的第三方CDN
- 依赖远程托管和RPC到远程服务的前端框架
- 其他类型的第三方SaaS嵌入
设计原则
选择分区cookie
此方案与现有分区cookie实现的主要区别在于第三方选择加入。一旦(未分区的)第三方cookie被废弃,必须使用新属性设置cookie,才能在跨方请求中发送。
从长远来看,这一原则符合最低特权原则。最初,这个新属性将限制cookie的行为,因为与未分区的第三方cookie相比,它将限制cookie可以发送的范围。但是,从长远来看,这些cookie将是跨党派环境中唯一可用的cookie。
尽管现有的软件和API需要更新以支持这一新的cookie属性,但我们相信,选择加入将是帮助从(未分区的)第三方cookie中移动网络而不会导致意外错误的最佳方式。有关更多信息,请参阅下面的“默认情况下对所有第三方cookie进行分区”部分。
仅通过安全协议发送
分区cookie只能由安全协议设置并通过安全协议发送。这有助于解决cookie的保密性和完整性较弱的某些方面。
避免占用大量内存
引入分区cookie的一个问题是用户机器上状态的扩散。对于未分区的第三方cookie,单个第三方只需要在用户的机器上设置一个cookie,该cookie可以用于用户访问的所有顶级网站的跨站点请求。删除未分区的第三方cookie后,第三方将需要为用户访问的每个顶级上下文设置一个cookie,从而在用户的机器上设置更多的cookie。
希望支持分区cookie的浏览器必须对每个分区可用于第三方域的cookie数量施加额外限制。
然而,用户代理也有必要以不允许恶意第三方学习有关用户的跨站点信息的方式来设计这些限制。有关更多详细信息,请参阅“CHIPS的替代设计”中的“限制分区中的cookie数量以应用每个域180个cookie的限制”。
详细设计
分区模型
如今,cookie是在设置它们的网站的主机名或域上键入的,即它们的主机密钥。在CHIPS之后,选择分区的cookie将在其分区密钥和主机密钥上进行双重键控。cookie的分区密钥是浏览器在向设置cookie的端点发出请求时访问的顶级URL的站点(即方案和可注册域)。
同样,请求的分区键是浏览器在请求开始时访问的顶级URL的站点。在与cookie具有相同分区密钥的请求中,浏览器只能发送具有Partitioned属性的cookie。
选择加入cookie属性
我们提出了一个新的cookie属性Partitioned,它必须由Set cookie标头指定,以表明cookie只能在设置cookie的同一分区中传递。任何未设置Partitioned属性的cookie最终都将在第三方上下文中被阻止。
使用分区的Set Cookie
以下是使用Partitioned属性的Set Cookie标头的示例:
Set-Cookie: __Host-SID=31d4d96e407aad42; SameSite=None; Secure; Path=/; Partitioned; Set-Cookie: abc=21ef; SameSite=None; Secure // blocked in 3p contexts
算法
以下是浏览器可以用来解析具有此属性的cookie行的算法。该算法可以添加到RFC6265bis的5.3节中。
- 让“分区键”为null。
- 如果属性名称大小写与字符串“Partitioned”不区分大小写匹配,则当用户代理发出请求时,“partition-key”应为顶级文档的站点。
- 将属性名称为“PartitionKey”、属性值为“PartitionKey”的属性附加到cookie属性列表中。
以下是存储分区cookie的算法。在用户代理检查__Host前缀之后,这些步骤可以添加到RFC6265bis的5.4节中。
- 如果cookie属性列表包含属性名称为“PartitionKey”的属性,并且属性值为null,则跳过以下步骤,将cookie插入cookie存储。
- 如果cookie属性列表不包含属性名称为Secure的属性,则中止这些步骤并完全忽略cookie。
- 将cookie的分区键设置为属性列表中属性名称为“PartitionKey”的元素的属性值。
此外,我们将在步骤5.4中修改算法的步骤19的第一部分,将分区密钥也包括在要检查的cookie属性列表中,这样,如果具有相同名称、域、仅主机标志和路径的两个cookie的分区密钥值不同,则它们可以在cookie存储中共存。
将分区cookie附加到请求
在第三方上下文中,分区cookie将在请求标头中发送,如下所示:
Cookie: __Host-SID=31d4d96e407aad42
注意:如果这是第一次向具有不同分区密钥的第三方发出请求,则不会发送cookie。换句话说,第三方将为每个顶级上下文获得一个新的标识符。
算法
以下是将分区cookie附加到请求的算法。这些步骤可以在第一步骤之后添加到RFC6265bis的第5.5节中描述的算法中。
对于cookie列表中的每个cookie,请执行以下操作:
- 如果cookie的分区键为null,请跳过此步骤的以下部分。
- 当用户代理启动请求时,让“请求分区密钥”成为顶级文档的站点。
- 如果cookie的分区密钥与请求分区密钥的字符串不完全匹配,则从cookie列表中删除该cookie。
示例用法
以下是如何使用分区cookie来满足上述关键场景部分中列出的用例的描述。对于这些示例,您可以假设所有资源都是从安全的来源发送的。
第三方定位器服务
让我们重新考虑一下shoes.com和embed.mass.com的例子:一种定位服务,它希望使用cookie来存储用户在shoes.com上的活动偏好(例如他们最喜欢的商店位置)。
删除第三方cookie后,当顶级网站不是maps.com时,embed.maps.com无法再设置cookie,除非它们包含Partitioned属性:
Set-Cookie: __Host-locationid=187; SameSite=None; Secure; HttpOnly; Path=/; Partitioned;
对分区密钥的域为shoes.com的embed.mass.com的任何后续请求都将包括以下标头:
Cookie: __Host-locationid=187;
但是,当浏览器导航到另一个网站时,浏览器不会将上面的Cookie标头发送到embed.mass.com。这使embed.mas.com能够存储用户最喜欢的shoes.com商店位置,但只有当顶级网站是shoes.com时,这些首选项才可由embed.mas.com.访问。这是为了确保embed.mas.com.cn不能使用此Cookie在不同的顶级网站之间链接用户的活动。
第三方客户支持小部件
让我们重新考虑retail.com的例子,它希望嵌入第三方客户支持小部件support.chat.com,以帮助用户在其网站上注册帐户。删除第三方cookie后,support.chat.com只能在顶级网站为retail.com时设置cookie,前提是该cookie具有Partitioned属性:
Set-Cookie: __Host-coversationid=a3e70; SameSite=None; Secure; HttpOnly; Path=/; Partitioned;
任何向分区密钥的域为retail.com的support.chat.com的请求都将包括cookie:
Cookie: __Host-coversationid=a3e70;
当用户导航到不同的顶级网站时,任何对support.chat.com的请求都会有不同的分区密钥,因此上面的cookie将不可用。这意味着support.chat.com无法使用cookie来识别顶级网站的用户。
CDN负载平衡
当用户访问example.com和static.cdn.com时,希望设置一个cookie来存储计算结果,这是引导该特定用户请求的最佳方式。他们可以使用Partitioned属性,使用以下Set Cookie标头来执行此操作:
Set-Cookie: __Host-lb=a3e7; SameSite=None; Secure; HttpOnly; Path=/; Partitioned;
只有当浏览器的顶级网站是example.com时,此cookie才可用于static.cdn.com。当浏览器导航到另一个顶级网站时,随后对static.cdn.com.的请求将不包括此cookie。
如何执行设计原则
安全属性
用户代理必须拒绝任何带有Partitioned且不包括Secure的cookie集。
HttpOnly属性
用户代理也可能强制分区cookie也包括HttpOnly属性,但我们不太相信他们应该要求它。确保分区cookie仅在网络堆栈上可用,使其不易受到XSS攻击。
SameSite属性
只有SameSite属性为None时,用户代理才能接受分区cookie。
注意:没有SameSite=None的分区cookie实际上只是同一个站点cookie,无论如何都不能在第三方上下文中发送。
限制第三方在单个分区中可以使用的cookie数量
第三方域的cookie jar的每个分区大小限制应该比现有的垃圾收集阈值(Chrome中每个域180个cookie)低得多。用户代理必须将第三方域限制为每个分区只能有一个或少量cookie。每个第三方在单个分区中的cookie数量由域决定,因此第三方无法通过注册新子域来规避此限制。
根据对该提案的反馈,即每个分区的cookie下限以及单个分区cookie的最大大小下限都会给开发人员带来问题,我们建议根据分区网站的cookie使用的内存总量进行限制。这个限制可能是10千字节。
用户代理可能会对cookie罐中分区cookie的数量实施一些全局限制。这是为了确保随着时间的推移,用户访问更多的顶级网站时,保存到其机器上的分区cookie的数量不会随着时间的增长而增加。
清除分区的cookie
如果第三方站点发送“清除站点数据”,则用户代理应仅清除当前顶级站点分区中该第三方可用的所有cookie。用户代理不得清除其他分区中第三方的cookie。这是为了防止滥用此处所述的跨站点跟踪矢量的能力。
浏览器可以选择提供用户控件来清除网站cookie的各个分区。
顶级网站不应能够清除其分区中的第三方cookie。这将为顶级站点提供一个潜在的攻击向量,以干扰在第三方框架中运行的代码。
Cookie Store API
我们建议对Cookie Store API进行适度更改,以支持分区Cookie:
- 添加一个可选的布尔字段,分区为CookieInit。这将允许脚本使用CookiesStore.set设置分区cookie。如果该字段不存在,则应将其视为错误。
- 向Cookie ListItem添加一个已分区的布尔字段。该字段将指示cookie是否分区给CookiesStore.get和CookiesStore.getAll的调用方。
- 添加一个可选的布尔字段,分区为CookiesStoreDeleteOptions。这将允许CookiesStore.delete的调用方指定是否要删除分区的cookie。如果该字段不存在,则默认为false。
存储访问API
无论用户在给定的上下文中通过存储访问API做出任何选择,分区cookie都应该是可访问的。即使用户拒绝或拒绝了访问存储的提示,分区cookie仍应可访问(在这种情况下,分区LocalStorage仍将可用,因此阻止对分区cookie的访问不会影响用户隐私)。
处理较旧或不兼容的客户端
新的cookie属性将在无法识别的旧客户端上被忽略,并返回到默认行为。由于这些cookie适用于第三方上下文,因此与SameSite=None不兼容的客户端可能会拒绝SameSite=None的cookie。
尽管不是必需的,但仍然建议仍然包括__Host前缀。即使不识别Partitioned属性的客户端仍然强制执行__Host前缀的语义。这将确保跨站点cookie绑定主机名,并且仅通过安全通道发送,这仍然是一个安全优势。
内存影响
根据Chrome的数据,我们估计每个分区10个cookie将满足目前网络上99%的现有跨站点cookie使用情况。根据28天内汇总的Chrome数据,我们估计,对于至少有25个cookie的Android Chrome用户,分区跨站点cookie将使cookie罐的大小平均增加约6%,而对于至少有25%cookie的桌面Chrome用户,平均增加约18%。
我们发现,满足跨站点cookie用例和内存影响之间的这种权衡是可以接受的,但用户代理可能希望对分区cookie jar施加额外的大小限制,例如对所有分区cookie的全局限制。
Service workers
服务工作者可以通过Cookie Store API访问Cookie,或者当他们使用fetch发送HTTP请求时(假设一个工作者ping到一个HTTP端点,该端点只是在其响应中回显请求的Cookie头)。除非服务工作者被分区,否则即使cookie是HttpOnly,未分区的cookie jar也将对工作者可用。由于这些原因,对服务工作者进行分区是保证分区cookie jar的唯一方法。
如果用户代理实现了服务工作程序分区,并且服务工作程序在第三方上下文中注册,则只有当cookie的分区密钥与工作程序注册的顶级站点匹配时,分区cookie才能呈现给工作程序。工作程序决不能访问分区密钥为工作程序来源的cookie,因为这将有效地使分区工作程序可以访问未分区的跨站点cookie。
Safari已经按工作程序注册时的顶级原点和服务工作程序的原点对服务工作程序进行了分区,因此服务工作程序只能与安装工作程序时与顶级页面相同的顶级原点的窗口进行交互。如果用户代理使用此方案对服务工作人员进行分区,则不存在将分区cookie暴露给服务工作人员的跨站点跟踪风险。
当启用动态分区时,Firefox中的服务工作者会被禁用,但他们正在致力于实现分区的服务工作者解决方案。
服务工作者被列为PrivacyCG的客户端存储分区方案中应分区的存储类型。他们的划分模型在这个解释中有更详细的描述。
浏览器扩展
扩展页
当扩展页面从其他站点加载子资源时,用于确定哪些分区cookie应包含在请求中的分区键必须是最高层框架的站点,如果扩展具有该框架的主机权限,则该框架不是扩展URL,否则分区键应为扩展URL。如果子资源请求来自扩展页面的顶级框架,则如果扩展具有对该站点的主机权限则分区键为子资源URL的站点,否则应为扩展网址。
Background contexts
某些浏览器中的扩展能够使用JavaScript API(例如Chrome、Firefox)在后台环境中读取Cookie(对于拥有主机权限的网站)。我们建议通过提供partitionKey字符串参数,让扩展指定从哪个分区加载其网站的分区cookie,以及可以在哪个分区中为其网站保存cookie,从而使扩展能够在加载cookie时选择使用哪个分区密钥。
值得注意的是,通过允许扩展后台上下文跨不同分区加载cookie,允许扩展使用分区cookie来存储跨站点标识符。这个问题将在“安全和隐私注意事项”中进一步讨论。
First-Party CHIPS
通常,顶级网站所有者(即“第一方”)会希望在自己的网站上使用SameSite=Lax/Strict cookie,因为这些cookie提供CSRF保护。
然而,考虑到第一方希望在对嵌入第三方iframe中的顶级站点的请求的响应中设置cookie。由于cookie的站点依赖于整个祖先链,因此第一方不能使用SameSite=Lax/Strict cookie。因此,第一方被迫设置SameSite=None cookie。
顶级站点希望为来自第三方框架中的请求的响应设置cookie。
但是,此cookie没有SameSite保护。恶意网站可以嵌入顶级网站,并可以访问这些cookie。
但是,此cookie可在嵌入先前顶级网站的任何网站上使用。
CHIPS后,第一方可以设置SameSite=None;来自嵌入式第三方框架的响应中的分区cookie。第一方的嵌入请求仍然可以访问此顶级网站上的这些cookie,因为cookie分区密钥只考虑顶级网站。
顶级站点可以设置SameSite=None;分区cookie。
与CHIPS之前的SameSite=None cookie不同,这些分区cookie仅在单个顶级网站上可用。如果恶意网站试图将第一方嵌入自己的网站,那么恶意参与者将无法看到SameSite=None;分区cookie。
恶意网站无法访问第一方顶级网站上设置的分区cookie。
需要注意的是,Partitioned并没有提供与SameSite=Lax/Strict相同的所有保护。例如,假设3p.com被恶意行为者破坏,并且仍然嵌入在1p.com上。在这种情况下,当1p.com是顶级网站时,攻击者可以将1p.com嵌入3p.com的框架中,并且攻击者可以访问1p.com的分区cookie。
安全和隐私注意事项
该提案利用定义新cookie属性的语义的机会,要求使用安全属性,将此功能限制在安全上下文中。
站点作为嵌入式框架更容易受到XSS攻击,因为这些上下文依赖于跨站点cookie来定义用户会话/状态。对跨站点cookie进行分区会降低XSS攻击的功能,因为攻击者需要将用户的浏览器导航到受损cookie的顶级站点,浏览器才能发送cookie。
对跨站点cookie进行分区不可避免地会导致用户机器上更多的状态扩散,因此对跨站点Cookie进行分区可能存在DoS风险,恶意嵌入站点可能会在不同的分区上设置许多cookie,以占用客户端机器上的内存。请参阅限制第三方在单个分区中可以使用的cookie数量,以了解有关该提案如何解决这一问题的更多信息。
与未分区的第三方cookie相比,具有分区属性的跨站点cookie不易受到CSRF攻击。这是因为只有当浏览器访问创建cookie的顶级网站时,才会在请求中发送分区cookie,因此恶意的顶级网站将无法使用现有的分区cookie伪造请求(除非他们破坏了发送cookie的顶级站点)。
该提案提出了一种跨站点cookie的替代设计,该设计不引入跨站点跟踪矢量。这是朝着更大的网络隐私改进迈出的一步:删除第三方cookie。
一个重要的隐私考虑因素是,分区cookie不得受每个域180个cookie限制的约束,否则它们可能会引入侧通道进行跨站点跟踪,如应用每个域180的cookie限制所述。
另一个隐私考虑因素是,具有主机权限的浏览器扩展可以规避分区cookie的隐私保证。扩展的后台上下文可以跨分区查询和存储cookie,这意味着它们可以跨分区存储跨站点标识符。不幸的是,由于扩展的性质,这种类型的攻击是不可避免的。即使我们从扩展的后台上下文中阻止分区cookie(甚至所有cookie),扩展仍然可以使用内容脚本将跨站点标识符写入DOM,站点自己的脚本可以将其复制到站点的分区cookie jar中。
CHIPS的替代设计
限制分区中cookie的数量
用户代理还可以强制执行的一个附加限制是限制所有第三方域中分区中的cookie数量。这个限制可以防止单个分区占用cookie罐中过多的空间。
我们选择不强制执行全局每个分区的限制,因为这将为第三方打开一个侧通道,让第三方了解另一个不同的第三方是否在同一顶级上下文中设置了cookie。
例如,假设每个第三方域每个分区被限制为1个cookie,而全局每个分区的限制为10个。恶意的第三方可以在一些顶级网站1p.com上嵌入来自多个域的帧,即邪恶[1-10].com,该网站设置了一个分区cookie。如果任何其他第三方在1p.com上设置了分区cookie,那么其中一个邪恶的[1-10].com cookie将被驱逐,恶意的第三方将得知另一个不同的主机设置了cookie。恶意的第三方可以使用这些信息来确定用户是否已经登录,或者他们是否正在使用由不同方托管的定位服务。
另一种攻击是eviv.com仅根据用户的个人属性或偏好设置cookie,从而与其他第三方进行通信。
一种潜在的规避方法是使全局每分区限制远大于每个第三方域的每分区限制,但尚不清楚全局每分区的相对大小必须是多少才能缓解这些攻击。
应用每个域180个cookie的限制
避免创建大内存占用的一种方法可能是在该域范围内的所有cookie(包括所有分区的分区cookie)上强制执行现有cookie限制(Chrome中每个域180个)。然而,这可能会创建一个无意的侧通道,恶意的第三方可以使用它来了解不同顶级分区中用户的信息。
考虑一下eviv.com是否嵌入在网站1p.com上,当用户访问1p.com时,它会在用户的机器上设置180个cookie。在其他顶级网站上,eviv.com会设置另一个cookie,该cookie会驱逐1p.com分区中eviv.com设置的一个cookie。当用户返回1p.com时,evil.com可以查看有多少cookie从其在1p.com上的分区中被逐出,以查看用户是否访问了另一个带有evil.com的网站。
即使用户代理对第三方每个分区可以拥有的cookie数量进行了额外的限制,这种攻击也可能发生。想象一下,eviv.com已经在许多顶级网站上嵌入了内容。在每个站点上,他们设置了N个cookie,即每个分区允许设置的最大值eviv.com。一旦用户访问了180/N个带有eviv.com嵌入的网站,一旦他们访问了另一个带有evil.com的网站,将超过全局限制,其他分区中的其他evil.com cookie将被驱逐。当用户返回到嵌入了evil.com的网站时,evil.com将检测到cookie已被驱逐。
eviv.com可以从这种类型的攻击中了解到特定用户的熵有多大,目前还没有研究。因此,目前尚不清楚相对的全局和每个分区的限制是什么,以防止eviv.com以这种方式了解有关用户的任何可识别信息。
DNS CNAME
网站可以选择使用DNS CNAME记录将子域委派/别名给第三方服务提供商。例如,网站myblog.example可能有一个子域名foo.myblog.example,该子域名可以映射到myblog.cms.example上专门为该网站提供服务的第三方端点。在这种情况下,浏览器将foo.myblog.example视为顶级网站的第一方,并且在最终发送到myblog.cms.example的请求中发送的任何cookie都在[foo.]myblog.example上隐式分区。
因此,任何发送到foo.myblog.example的cookie都不会受到跨站点cookie限制,仍然会发送到myblog.cms.example。
但是,这种模式有几个安全缺陷:
- myblog.cms.example需要获取并提供为foo.myblog.example颁发的TLS证书。
- myblog.example上设置的所有域cookie都会发送到myblog.cms.example,包括myblog.exe上其他子域设置的潜在敏感数据。
此外,这增加了开发人员的实现和部署复杂性。
参考和确认
鸣谢
我们要感谢Lily Chen、Steven Bingler、Rowan Merewood和Jeffrey Yasskin的见解和建议,他们帮助我们制定了这项提案。
工具书类
- Chromium Blog: Building a more private web: A path towards making third party cookies obsolete
- Clear-Site-Data for partitioned storage can be used for cross-site tracking · Issue #11 · privacycg/storage-partitioning
- Cookie Store API Explainer | cookie-store
- cookie_monster.h - Chromium Code Search
- draft-ietf-httpbis-rfc6265bis-07 - Cookies: HTTP State Management Mechanism
- [Dynamic FPI] The user and password for Facebook did not transfer to messenger.com
- Firefox 86 Introduces Total Cookie Protection - Mozilla Security Blog
- [FirstPartyIsolation] Failed to sign in to the pixnet.net
- Fx with FPI feature wrongly displays that sign-in on youtube has failed even though it did not
- Googleusercontent.com can trip you up, if you disable third-party cookies · Kerika
- Headless CMS Github Gist · LOGIN-issues.md
- Headless content management system - Wikipedia
- HTML Standard
- Intelligent Tracking Prevention 2.1 | WebKit
- Isolate service workers and DOM cache by first party domain
- Let embedees optionally request access to partitioned cookies and storage · Issue #75 · privacycg/storage-access
- michaelkleber/privacy-model: A Potential Privacy Model for the Web: Sharding Web Identity
- mikewest/http-state-tokens: Incrementally better HTTP state management.
- Principle of least privilege - Wikipedia
- privacycg/first-party-sets
- privacycg/storage-partitioning: Client-Side Storage Partitioning
- quota-storage-partitioning/explainer.md at main · wanderview/quota-storage-partitioning
- SameSite=None: Known Incompatible Clients - The Chromium Projects
- sbingler/Origin-Bound-Cookies
- Secure Contexts
- Software as a service use case for FPS · Issue #33 · privacycg/first-party-sets
- State Partitioning - Mozilla | MDN
- View Source shows source code of login page instead of current webpage on local django server
- Workers at Your Service | WebKit
- [Working] Fix Google Drive Downloads Not Working in Microsoft Edge – Gadgets To Use
- 登录 发表评论