Cookie是便于向网站添加持久化状态的方式之一。随着时间推移,它们的能力得到了扩展和进化,也造成了很多历史遗留问题。为了解决这个问题,浏览器产商(包括Chrome,Firefox,和Edge)改变了他们的处理逻辑以加强个人隐私的默认配置。

每一个cookie都是拥有一些为了控制何时何处被使用的键值对。你可能已经通过这些属性去设置过期时间或者指明当前cookie只能在https协议下传输。服务器通过在响应中携带Set-Cookie头来设置cookie。想要了解详细信息,可以深入阅读RFC6265bis,现在只是快速的回顾一下。

现在假设你的博客网站需要向用户推送一个“最新内容”的提示。用户可能会取消这个提示并且一段时间内他们也不会再看这个提示。你可以将这种喜好设置在一个cookie中,给它设置一个月(2,600,000 seconds)后到期,并且只能在HTTPS协议下传输。这个头部可能看起来像这样:

Set-Cookie: promo_shown=1; Max-Age=2600000; Secure



服务器通过Set-Cookie头来设置cookie

当你的读者正在访问一个做了上面这些设置的页面,进一步说他们正在使用HTTPS进行连接并且这个cookie存续时间小于一个月,那么他们的浏览器就会请求里携带如下的头部:

Cookie: promo_shown=1



浏览器通过Cookie头回传cookie

在javascript中通过使用document.cookie可以读取或者添加站点的cookie。对document.cookie进行赋值操作将会覆盖对应键的cookie。举个例子,尝试在你的浏览器javascript console中输入以下语句:

> document.cookie = "promo_shown=1; Max-Age=2600000; Secure"
< "promo_shown=1; Max-Age=2600000; Secure"

读取document.cookie将会打印出所有能够在当前环境中获取到的cookie,每个cookie通过一个分号分隔

> document.cookie;
< "promo_shown=1; color_theme=peachpuff; sidebar_loc=left"



JavaScript中可以通过使用document.cookie获取cookie

如果你尝试在一些流行的站点上读取cookie,你会明显发现它们中大多数设置了超过3个cookie。在大多数场景下,这些cookie将会根据一系列因素携带在对应域名的请求中。对于你的用户来说,一般上行带宽一般比下行带宽拥有更多的限制,所以将大量携带在cookie对外的请求上将会导致将会导致请求获取第一个字节的延迟。为了合理控制设置的cookie数量。通过设置Max-Age属性来帮助保证cookie在不需要的时候及时被清除掉。

什么是自有和第三方cookie?

重新访问前面一系列站点,很可能会发现有些cookie会在很多不同域名下出现,不仅仅是当前正在访问站点域名。当前站点域名(显示在浏览器地址栏里面的域名),被称为自有域名。同样的,那些来自当前站点外域名的cookie被称为第三方域名。这只是相对用户的角度并不是一个绝对的标签,同样的cookie既可能是自有的也可能是第三方的,取决于用户当前访问的站点。



一个页面上的cookie可能来自多个不同域名

继续前面的例子,假设你的一篇博客当中有一张极其可爱的小猫图片,这张图片存储在/blog/img/amazing-cat.png下。由于这张图片太可爱了,其他人在他们的网站上直接使用了它。如果一个用户访问过你的博客将会有promo_shown cookie,当他在其他网站上看到这张直接被引用的图片时,图片的请求将会携带这个cookie。这并不是对任何人都特别有用,因为promo_shown在其他人的网站上并不是对任何请求都有用,这样只会增加请求的负载。

如果这并不是有意达成的效果,那在什么情况下你需要这样了。这是一种允许在第三方站点环境上保持会话状态的机制。例如,如果在你的站点页面上添加了一个YouTube video,那么访问者将会在播放器中看到一个"watch later"的操作项。如果访问者已经登陆了YouTube,第三方cookie将会使得用户通过一步点击"watch later"按钮收藏这个视频到YouTube供后续观看,而不需要提醒他们登陆YouTube或者离开当前站点并跳转到YouTube。



在第三方环境下访问不同的页面cookie将被传输

万维网文化属性之一是开放共识。这使得许多人创造自己的内容和应用程序成为可能。然而这也带来了一些安全和隐私风险。跨站请求伪造攻击(Cross-site request forgery attack-csrf)制造依赖于那些cookie将会被携带在针对指定域名的请求中,而不论这些请求具体由谁触发。举个例子,当你访问了evil.example并且它可以触发your-blog.example的请求,那么浏览器将会很乐意携带上关联的cookie。如果你的博客对这些请求的验证不够仔细那么evil.example可以触发删除和添加内容的任何操作。

用户现在更加清醒的意识到cookie怎样被用来跟踪他们在不同页面的活动轨迹。然而直到现在仍然没有一种明确的方式表明对cookie本来用意。你的promo_showncookie本应该只被用在自有站点环境下,而嵌入到第三方站点的组件所携带的会话cookie是被用来保持会话状态。

使用SameSite明确表明cookie的用途

SameSite属性的引入(定义在RFC6265bis)允许你表明你的cookie被用在第三方或者自己的站点环境下。明白站点的确切意义将会大有裨益。站点是域名后缀和它前面部分的混合。例如,www.web.dev域名站点是web.dev域名站点的一部分。

关键词same-site

如果用户在www.web.dev发起了一个向static.web.dev的图片请求这是一个same-site请求。

public suffix list定义了这些,不仅是像.com这样的顶级域名也包括像github.io这样的域名。这使得your-project.githubmy-project.github被认为为不同的站点。

关键词cross-site

如果用户在your-project.github.io站点发起了一个向my-project.github.io的请求,这是一个cross-site请求。

在cookkie中引入SameSite属性三种控制这种行为的方式。你可以不指定指定这个属性,或者通过使用StrictLax来限制cookie只在same-site请求下携带。

如果你设置SameSite属性为Strict,那么你的cookie将会只在自有环境下发送。在用户看来,那个cookie只会在匹配当前显示在地址栏的站点时才会被发送。所以,假设Promo_showncookie如下设置:

Set-Cookie: promo_shown=1; SameSite=Strict

那么当你的用户在你的站点上是,cookie将会如预期被发送。然而当从一个指向你站点的引用链接,详细地说当从另一个站点或者从通过一个朋友发给你的一个链接,在初始请求里并不会这个cookie并不会被发送。当你拥有一些关联后置于初始导航你站点功能的cookie的情形下,例如修改密码或者下订单的情形下,这是极其有用的,但是对于promo_shown这个功能限制太多。如果你的用户通过链接进入你的站点,他们希望cookie能被发送,这样他们的设置能够生效。

当你的用户初始导航到你的网站上时cookie将会被发送,这就是SameSite=Lax的使用场景。让我们继续回顾那个引用小猫图片的例子,那个例子中其他站点正在引用你的内容。他们直接使用你的小猫图片并且提供了一个指向你的原始文章的链接地址。

<p>Look at this amazing cat!</p>
<img src="https://blog.example/blog/img/amazing-cat.png" />
<p>Read the <a href="https://blog.example/blog/cat.html">article</a>.</p>

cookie这样设置:

Set-Cookie: promo_shown=1; SameSite=Lax

当浏览者在其他人的博客上请求amzing-cat.png,cookie将不会被发送。然而当读者通过一个点击一个指向你站点cat.html的链接时,cookie将会被发送。这样的话,使得Lax成为设置影响网站外观cookie的好选择而Strict将会对用户那些关联到当前操作的cookie极其有用。

注意

StrictLax对于你的站点安全都不是一个完整的解决方案。cookie将会作为用户输入的一部分,你需要像对待其他用户输入一样。意味着,需要对这些输入进行脱敏和验证。绝对不要将服务端的重要数据存储在cookie中。

最后还有一个不设置这个值的默认方式,那么cookie将会在所有上下文情形下被发送。在最新的RFC6265bis草案中这种方式被SameSite=None这个新值明确表达。这表明你可以通过设置SameSite=None来明确表明你希望cookie在所有第三方上下文环境下被发送。

!(None Lax Strict)[https://webdev.imgix.net/samesite-cookies-explained/samesite-none-lax-strict.png]

通过NoneLaxStrict来明确表明cookie的使用上下文

★ 如果你提供了供其他网站使用的服务,例如嵌入式组件、嵌入式多媒体内容、联合程序、广告、跨站登陆那么你需要使用None来明确表明的意图。

未设置SameSite属性默认行为的变化

尽管SameSite属性得到广泛支持,很不幸的是并没有很广泛的被开发者使用。cookie在所有地方都会被发送的开放默认行为使得所有场景都能正常工作,但是这样提高了用户受到CSRF和意外信息泄漏的风险指数。为了号召开发者明确表明他们的意图并且提供用户更高的安全使用体验,IETF发布了一个提议,Incrementally Better Cookies提供了两项关键改进:

  • 那么没有设置SameSite属性的cookie将等同设置了SameSite=Lax
  • cookie设置SameSite=None必须同时设置Secure,这意味着需要在更安全的环境下传输。

Chrome在84版本实现了以上默认行为。Firefox在69版本可以测试使用,并且未来会加入默认配置中。为了在Firefox中测试这些行为,打开about:config然后network.cookie.sameSite.laxByDefault。Edge也计划改变其默认行为。

原文

https://web.dev/samesite-cookies-explained/

samesite-cookie详解(译文)的更多相关文章

  1. Cookie 详解以及实现一个 cookie 操作库

    Cookie 详解以及实现一个 cookie 操作库 cookie 在前端有着大量的应用,但有时我们对它还是一知半解.下面来看看它的一些具体的用法 Set-Cookie 服务器通过设置响应头来设置客户 ...

  2. Cookie的使用、Cookie详解、HTTP cookies 详解、获取cookie的方法、客户端获取Cookie、深入解析cookie

    Cookie是指某些网站为了辨别用户身份.进行session跟踪而存储在用户本地终端上的数据(通常经过加密),比如说有些网站需要登录才能访问某个页面,在登录之前,你想抓取某个页面内容是不允许的.那么我 ...

  3. cookie详解

    一.cookie详解 (1)设置cookie 每个cookie都是一个名/值对,可以把下面这样一个字符串赋值给document.cookie: document.cookie="userId ...

  4. ASP.NET 操作Cookie详解 增加,修改,删除

    ASP.NET 操作Cookie详解 增加,修改,删除 Cookie,有时也用其复数形式Cookies,指某些网站为了辨别用户身份而储存在用户本地终端上的数据(通常经过加密).定义于RFC2109.它 ...

  5. 网络基础 cookie详解

    cookie详解 by:授客 QQ:1033553122 cookie干嘛用的? 参见文章http 会话(session)详解: 网络基础 http 会话(session)详解   cookie分类 ...

  6. cookie详解(含vue-cookie)

    今天看到一篇cookie的文章,写的特别详细,感谢 晚晴幽草轩 的分享,原文链接http://mp.weixin.qq.com/s/NXrH7R8y2Dqxs9Ekm0u33w 原文如下,记录到此供以 ...

  7. Session和Cookie详解(1)

    面试常问的有关session和cookie的问题: 1.session在分布式环境下怎么解决 2.集群下如何保证session踩中 3.cookie的大小 4.服务器怎么识别一个用户的 5.sessi ...

  8. JavaWeb Cookie详解

    代码地址如下:http://www.demodashi.com/demo/12713.html Cookie的由来 首先我们需要介绍一下,在Web开发过程中为什么会引入Cookie.我们知道Http协 ...

  9. [转]Cookie详解

    从事 Web 开发已有近17个月:在学以致用的工作学习里,对于不怎么使用的部分,多少有些雾里探花的窘迫感-差不多是了解一二,然而又非真切的明晰:这就使得再用的时候,总要去再搜索一番:如此颇为难受,倒不 ...

  10. Java web Cookie详解(持久化+原理详解+共享问题+设置中文+发送多个Cookie)

    Java web Cookie详解 啥是cookie? 查询有道词典得: web和饼干有啥关系? 这个谜底等等来为大家揭晓 会话技术 web中的会话技术类似于生活中两个人聊天,不过web中的会话指的是 ...

随机推荐

  1. time模块:时间戳和格式化好的时间表示方法及互相转换方法

    1.导入time模块   import time 2.获取当前时间的时间戳   time.time() 3.获取当前格式化好的时间   time.strftime(想要获取的格式) 4.时间戳和格式化 ...

  2. Docker Swarm 集群环境搭建及弹性服务部署

    上一篇文章<Docker Swarm 集群管理利器核心概念扫盲>中我们把 Swarm 重要的概念性知识给大家讲解了一波,理论完事就该实战了,这篇文章带大家从零开始,搭建 Docker Sw ...

  3. Spock测试套件入门

    目录 Spock测试套件 核心概念 整体认识 前置.后置 同junit的类比 Feature 方法 blocks 典型的用法 异常condition then和expect的区别 cleanup bl ...

  4. 对比ERP解读企业资产管理EAM在电力行业应用

    对比ERP解读企业资产管理EAM在电力行业应用 .关于EAMEAM (Enterprise Asset Management)企业资产管理,是面向固定资产占企业资产主要部分的资产密集型(Capital ...

  5. rabbitmq的安装&学习

    主要按照 https://www.cnblogs.com/web424/p/6761153.html https://www.cnblogs.com/qiyebao/p/4822583.html 学习 ...

  6. RXJAVA源码之多线程

    在不指定线程的情况下, RxJava 遵循的是线程不变的原则,即:在哪个线程调用 subscribe(),就在哪个线程生产事件:在哪个线程生产事件,就在哪个线程消费事件.如果需要切换线程,就需要用到 ...

  7. 浅谈c++(一)

    本人为菜鸟一枚,如有错误,欢迎指正. 由于上半年学了C语言,为了更好的过渡到C++,我将在未来展示一下两者的不同以及优缺点.在c++中,不得不谈到类.这是C++中最重要的语法特征.我们可以通过它,定义 ...

  8. el-table行点击事件row-click与列按钮事件冲突

    需求简述 表格用el-table实现,操作列的编辑按钮点击事件正常实现.现要为行加一点击事件,即row-click.加上后,发现点击操作列的编辑按钮时,会触发按钮本身事件,同时会触发行点击事件.第一版 ...

  9. jQurey轮播插件slides简单使用教程

    动态演示地址: http://www.zqunyan.com/zgproduction/slidesjs/index.html 简介就不多说了,网上有很多,复制粘贴没意义,会想到用这个插件就代表已经了 ...

  10. Python练习题 043:Project Euler 015:方格路径

    本题来自 Project Euler 第15题:https://projecteuler.net/problem=15 ''' Project Euler: Problem 15: Lattice p ...