Cookie或将被替换!Chrome工程师提议新型HTTP状态管理协议
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Cookie或将被替换!Chrome工程师提议新型HTTP状态管理协议相关的知识,希望对你有一定的参考价值。
Cookie或将被替换!Chrome工程师提议新型HTTP状态管理协议
问题
-
Cookie允许无状态的HTTP协议支持有状态会话,在web上,我们依靠Cookie实现了很多有趣的功能。即便如此,Cookie依然还是有很多问题:使用起来不够安全,浪费资源,使用一种令人惊讶的方式追踪用户在网络上的活动。
-
安全:这些年我们引入过很多的特性,试图提供合理的安全属性给那些关心安全的开发者,但也只是降低了安全问题而已:
- Cookies对javascript来说默认是可用的(通过document.cookie),这使得一次XSS平滑升级能偷窃持久凭证(然后能使用Cookies在内存中产生类似于Spectre的有效***)。虽然十年前引入了HttpOnly属性,目前也只有大概8.31%的人使用Set-Cookie进行了设置。
默认情况下,Cookie会被发送到非安全的源,这会导致凭据被盗。Secure属性将为安全的源Cookie锁定,这很好!尽管如此,今天只有大概7.85%的人Set-Cookie进行了设置。
Cookies经常在请求发送者没有任何迹象的情况下被设置。SameSite属性用于减少CSRF风险,但是事实上,目前只有大概0.06%的人使用Set-Cookie进行了设置。
Cookies使用属性来降低安全风险,然而它依然不符合我们对其他web资源设置的安全边界。它们通过给定的注册域名跨域访问,它们忽略端口和scheme(意味着它们很容易被网络***者伪造),它们能缩小到详细的路径。这些特征使得它们很难落地,很难为平台的其他地方降低同源策略起到激励作用。
效率低:服务能通过一个给定的注册域名存储很多Cookie,并且很多Cookie可以通过HTTP请求被发送。不同的浏览器供应商有不同的限制,但是它们都很高。例如Chrome,允许为每一个域名存储180个Cookie,相当于硬盘上的724kB。幸运的是,如果请求头中发送了很多的数据,服务器通常会出问题。Cookie滥用的情况事实上非常多:一般(未压缩)的Cookie请求头大小是409字节,但是90%的请求是1589字节,95%的请求是2549字节,99%的请求是4601字节(~0.1%的Cookie头非常大,超过10kB)。
隐私:Cookies一方面能开启监控(我希望我们可以在某种程度上解决这个问题,通过类似HTTP上Cookie的弊端描述的机制那样放弃它),另一方面,用户可能不了解全面跟踪的事情。
注意:上面提到的所有统计数据来自于Chrome的2018年7月的数据。我非常欢迎其他浏览器供应商提供类似的数据,但是我假定它们在同一个数量级。
提议
让我们通过为开发人员提供一条良好的路径来解决上述问题,可以起到防范安全的作用。用户代理能管理HTTP状态,相当于在用户这边通过为用户浏览的每个安全的源生成一个唯一的256位大小的Token。这个Token能作为结构化的HTTP请求头,交付给源:
Sec-HTTP-State: token=*J6BRKagRIECKdpbDLxtlNzmjKo8MXTjyMomIwMFMonM*
这个标识或多或少像代理控制的Cookie,包含一些重要的差别:
1.代理管理Token值,而非服务端管理。
2.Token将仅仅在网络层可用,JavaScript不可用。
3.用户代理将只为每个源产生一个256位大小的Token,并且将不会暴露任何它产生的Token给源。
4.Token将不会被产生,或者传递给不安全的源。
5.默认情况下,Token将会在相同网站的请求中传递。
6.Token持续存在,直到它被服务或者用户或者代理重置。
这些差别可能不能覆盖所有的用户场景,但是一般情况下足够了。对于不够用的情况,我们支持开发者通过HTTP头的Sec-HTTP-State-Options选项来进行控制。选项如下:
一些服务将必须跨站访问它们的Token。另外一些服务可能希望将范围缩小到同源请求。两种方案都支持:
Sec-HTTP-State-Options: ..., delivery=cross-site, ...
或者
Sec-HTTP-State-Options: ..., delivery=same-origin, ...
一些服务将希望限制Token的生命周期。我们允许它们去设置TTL(单位秒):
Sec-HTTP-State-Options: ..., ttl=3600, ...
时间过期之后,这些Token的值将自动被重置。服务可能也希望去明确指定Token的重置(例如登出)。设置TTL为0能达到目的:
Sec-HTTP-State-Options: ..., ttl=0, ...
在任何情况下,都可以向当前运行的页面通知用户的状态变化,以便执行重置操作。当重置发生,用户代理能发送一个叫http-state-reset的消息到源的BroadcastChannel(并且可能唤醒服务器响应用户重置):
let resetChannel = new BroadcastChannel(‘http-state-reset‘));
resetChannel.onmessage = e => { /* Do exciting cleanup here. */ };
对一些服务来说,代理产生Token将足够状态维护。他们能像一个会话标识一样处理它,并且绑定用户状态到服务端。另一些服务需要额外工作来保证信任Token的来源。为此,服务能产生一个唯一id,服务端使用它跟会话id关联起来,并且通过HTTP响应头传递它到代理:
Sec-HTTP-State-Options: ..., key=*ZH0GxtBMWA...nJudhZ8dtz*, ...
代理将存储这个id,并且使用它去给数据集生成签名,减少Token抓取的风险:
Sec-HTTP-State: token=*J6BRKa...MonM*, sig=*(HMAC-SHA265(key, token+metadata))*
举例,使用已经定义的Signed Exchanges格式来签名请求,除了重放***之外,其他情况都很难使用被盗的令牌。在请求中包含时间戳可以减少重放***的可能性。
注意:这种特定情况没有被解决。我们需要去重新审视人们在绑定Token等方面所做的工作,以确定正确的威胁模型是怎么样的。把它当成是一个方向去探索,这还不是一个深思熟虑的稳妥解决方案。
FAQ
继续上面提到的三个方面,这个针对创建一个固化的状态Token的建议,映射到与平台其余部分的相同安全原语,减少客户端的传输成本,并且默认不支持跨站追踪。
我们应该放弃Cookie?
当然不是!
那为什么提出本方案?
Cookie是不好的,并且我们应该发现一种方式去放弃它。但是这需要花费一段时间。该提案旨在提供一种补充,即使在Cookie同时存在的情况下,也是有价值的方案,给我们一种推动开发者从一个方案增加另一个方案的能力。
与Cookie对比,它完全是一个新的东西?
不完全是。
开发人员可以通过设置像“__Host-token=value1; Secure; HttpOnly; SameSite=Lax; path=/”这样的Cookie来获得几乎所有上面提到的属性。这不是一个完美的方案,但它非常好。我了解到的现状是,开发人员需要了解各种标志和命名约定,才能通过Set-Cookie:token = value这样的方式使用它。默认值很重要,这似乎是最简单的事情。比起让开发人员使用4个属性,以及采用奇怪的命名约定来说,将它合并到1个属性里更好。
我们还可以重新考虑服务器端状态在代理上维护。我觉得使用用户代理控制会话标识符,而不是服务器设置的大量键值对,更优雅,更节约用户的资源。
你期待大家怎么从Cookie迁到这个方案上?
用户代理可以通过在传出的请求头附加Sec-HTTP-State的方式,逐步迁移,来广播对新功能的支持(默认情况下设置这个值,或允许开发人员根据上面的讨论选择性支持)。
开发人员可以开始将新机制用于其身份验证基础架构,这些机制最大程度地受益于源的作用域,与现有Cookie基础架构并行。随着时间的推移,他们可以建立一个他们所依赖的客户端状态列表,并开始在会话标识符和状态之间构建服务器端映射。一旦该机制成熟了,以逐步迁移的方式迁移。
最终,您可以想象让开发人员能够完全迁移,完全关闭其网站的Cookie(例如,通过Origin Manifests)。最终,我们还可以让开发人员选择使用Cookie而不是完全放弃。
在整个时间线的任何时刻,用户代理都可以像HTTP上Cookie的弊端里提到的那样,通过对Cookie子集进行限制来开始迁移。
对于多应用的源,这种迁移是不是很困难?
是的。这似乎是一个bug,又是一个功能。对于源和应用来说,1:1关系会更好。在同源的应用程序之间没有安全边界,我假设存在一个其他应用似乎没有多大价值。鼓励不同的应用在不同的源上运行,在它们的功能之间创建实际的隔离。
该提案是否对隐私属性有重大改变?
不完全是。绝大多数没有。也就是说,人们仍然可以使用这些Token来跟踪源的用户,就像他们今天使用Cookie一样。人们需要通过设置Token的delivery成员来声明这个意图,有一点小的要求,需要用户代理以某些方式对该声明作出合理的响应,但就其本身而言,技术能力几乎没有变化。
尽管如此,它仍然比现状有一些优势。例如:
1.这些Token不会以明文形式发送,这降低了监控的风险。
2.用户代理控制Token的值,这样可以降低在用户本地磁盘上暴露用户敏感信息的风险,降低暴露您和用户之间TLS终端的风险。
3.默认情况下,delivery选项会将Token限制为同源请求。假设我们遵循Cookie的SameSite 约定,用户跨站访问,需要明确说明Token可以跨站(此时用户代理才会做出相应的处理)。
用户可以如何管理用户代理?
就像今天使用Cookie一样,用户可以选择不将此Token发送到任何地方。用户代理会朝着那个目标努力,但用户也可以随时选择不适用用户代理。
相关阅读:
- 如何优雅的设计API
- 正则表达式引发的惨案
- Envoy为什么能战胜Ngnix——线程模型分析篇
本文作者 Mike Wes,在Google的Chrome团队就职,邓启明翻译。转载本文请注明出处,欢迎更多小伙伴加入翻译及投稿文章的行列,详情请戳公众号菜单「联系我们」。
高可用架构
改变互联网的构建方式
以上是关于Cookie或将被替换!Chrome工程师提议新型HTTP状态管理协议的主要内容,如果未能解决你的问题,请参考以下文章