为什么添加SameSite

  • cookies面临的两个问题:用户隐私 / CSRF(跨站请求伪造)
  • 明确cookie的使用范围,减少被攻击的可能
  • 客户端发送 HTTP 请求到服务器
  • 当服务器收到 HTTP 请求时,在响应头里面添加一个 Set-Cookie 字段
  • 浏览器收到响应后保存下 Cookie
  • 之后对该服务器每一次请求中都通过 Cookie 字段将 Cookie 信息发送给服务器。

cookie的一些属性

浏览器cookie和same-site

  • Name/Value

    • 用 JavaScript 操作 Cookie 的时候注意对 Value 进行编码处理。
  • Expires

    • Expires 用于设置 Cookie 的过期时间。比如:

    • Set-Cookie: id=a3fWa; Expires=Wed, 21 Oct 2015 07:28:00 GMT;

    • 当 Expires 属性缺省时,表示是会话性 Cookie,像上图 Expires 的值为 Session,表示的就是会话性 Cookie。当为会话性 Cookie 的时候,值保存在客户端内存中,并在用户关闭浏览器时失效。需要注意的是,有些浏览器提供了会话恢复功能,这种情况下即使关闭了浏览器,会话期 Cookie 也会被保留下来,就好像浏览器从来没有关闭一样。

    • 与会话性 Cookie 相对的是持久性 Cookie,持久性 Cookies 会保存在用户的硬盘中,直至过期或者清除 Cookie。这里值得注意的是,设定的日期和时间只与客户端相关,而不是服务端。

  • Max-Age

    - Max-Age 用于设置在 Cookie 失效之前需要经过的秒数。比如:
    - Set-Cookie: id=a3fWa; Max-Age=604800;
    - Max-Age 可以为正数、负数、甚至是 0。
    - 如果 max-Age 属性为正数时,浏览器会将其持久化,即写到对应的 Cookie 文件中。
    - 当 max-Age 属性为负数,则表示该 Cookie 只是一个会话性 Cookie。
    - 当 max-Age 为 0 时,则会立即删除这个 Cookie。
    - 假如 Expires 和 Max-Age 都存在,Max-Age 优先级更高。
    
  • Domain

    • Domain 指定了 Cookie 可以送达的host。假如没有指定,那么默认值为当前文档访问地址中的主机部分(但是不包含子域名)。
    • 不能跨域设置 Cookie
  • Path

    • Path 指定了一个 URL 路径,这个路径必须出现在要请求的资源的路径中才可以发送 Cookie 首部。比如设置 Path=/docs,/docs/Web/ 下的资源会带 Cookie 首部,/test 则不会携带 Cookie 首部。

    • Domain 和 Path 标识共同定义了 Cookie 的作用域:即 Cookie 应该发送给哪些 URL。

  • Secure属性

    • 标记为 Secure 的 Cookie 只应通过被HTTPS协议加密过的请求发送给服务端。使用 HTTPS 安全协议,可以保护 Cookie 在浏览器和 Web 服务器间的传输过程中不被窃取和篡改。
  • HTTPOnly

    • 设置 HTTPOnly 属性可以防止客户端脚本通过 document.cookie 等方式访问 Cookie,有助于避免 XSS 攻击。
  • SameSite

    • SameSite 是谷歌 2 月份发布的 Chrome80 版本中默认屏蔽了第三方的 Cookie,更大程度的防止跨域之间CSRF和保护用户隐私,借用Token+SameSite形式有效的解决CSRF问题。

SameSite属性值

  • SameSite属性用来限制第三方 Cookie,减少安全风险,有三个值:

    • Strict:仅允许一方请求携带 Cookie,即浏览器将只发送相同站点请求的 Cookie,即当前网页 URL 与请求目标 URL 完全一致
    • Lax:允许部分第三方请求携带 Cookie
    • None:无论是否跨站都会发送 Cookie
  • Strict

    • Strict最为严格,完全禁止第三方 Cookie,跨站点时,任何情况下都不会发送 Cookie。换言之,只有当前网页的 URL 与请求目标一致,才会带上 Cookie。
    • Set-Cookie: CookieName=CookieValue; SameSite=Strict;
  • Lax

    • Lax规则稍稍放宽,大多数情况也是不发送第三方 Cookie,但是导航到目标网址的 Get 请求除外。
    • Set-Cookie: CookieName=CookieValue; SameSite=Lax;
  • None

    • Chrome 计划将Lax变为默认设置(80版本已实施)。这时,网站可以选择显式关闭SameSite属性,将其设为None。不过,前提是必须同时设置Secure属性(Cookie 只能通过 HTTPS 协议发送),否则无效。
    • Set-Cookie: widget_session=abc123; SameSite=None; Secure

SameSite影响

samesite.png

  • 从上图可以看出,对大部分 web 应用而言,Post 表单,iframe,AJAX,Image 这四种情况从以前的跨站会发送三方 Cookie,变成了不发送。

  • Post表单:应该的,学 CSRF 总会举表单的例子。

  • iframe:iframe 嵌入的 web 应用有很多是跨站的,都会受到影响。

  • AJAX:可能会影响部分前端取值的行为和结果。

  • Image:图片一般放 CDN,大部分情况不需要 Cookie,故影响有限。但如果引用了需要鉴权的图片,可能会受到影响。

解决方案

  • 临时方案可设置 SameSite 为 None,必须同时设置Secure属性 (Set-cookie: key=value; SameSite=None; Secure)

  • 合理的解决方案简单总结应该是按照谷歌浏览器规则:

    • 默认设置 SameSite=Lax ,需要第三方cookie的则设置为none,CSRF Token会话类Cookies设置Strict(添加SameSite就是为了防止CSRF攻击)

netflix默认设置SameSite值为Lax

新版本的chrome浏览器(80版本之后),7月14后灰度测试,7月28基本覆盖大部分chrome用户