关于防CSRF你须要了解的另外一种方法

前言

网站一般会使用 cookie 来记录用户的登陆状态,但并不是安全,由于 cookie 被容许在第三方网站(也不只限于第三方)发起的请求中携带,所以利用这一点能够达到 CSRF 攻击。本文再也不对 CSRF 的原理做过多阐述,点击这里了解CSRF
若是别人问起防 CSRF 的方法有哪些,你们一般会说出:Token + Referer,该方案在业界已经很是成熟。当一个问题有了解决办法后,就很人有人会去了解别的方案,我想听听不一样的声音。html

有位社会人曾经说过:有趣的灵魂万里挑一。

本文给你们介绍另外一种防 CSRF 的方法。json

第三方请求

开始前咱们先了解一下第三方请求,什么样的请求被称为第三方请求?简单来讲就是在一个网页上发起一个不一样源的请求,那么咱们能够称为第三方请求。 安全

在一个页面上发起一个第三方请求能够分为有 异步请求 和 同步请求:
一、异步请求 指的是在当前页面上经过 scriptlinkimgfetchXHR 等方法发起的请求,这些都不会让页面发生变化,也不会打开新的页面。
二、同步请求 指的是在当前页面点击 <a> 标签,或 <form>提交、 JS 调起的 location.hrefwindow.open() 等方式发起的请求,这些方式可能会使当前页面刷新或者打开新的页面。cookie

第三方cookie

经过 a.com 的页面发起 a.com 的请求,会带上第一方 cookie (first-party cookie)。
经过 a.com 的页面发起 b.com 或 c.com 的请求,会自动带上第三方 cookie (third-party cookie)
CSRF 就是利用第三方请求会带上第三方 cookie 的弱点来达到在一个不信任的域下也能够达到的危险操做。dom

关于SameSite

正如文章开头所说的防 CSRF 能够直接上方案 Token + Referer,可是人家 Google 就是要改变世界,怎么说? Google 提了一份草案 ,给 cookie 新增 SameSite 属性,经过这个属性能够标记哪一个 cookie 只做为同站 cookie (即第一方 cookie,不能做为第三方 cookie),既然不能做为第三方 cookie ,那么别的网站发起第三方请求时,第三方网站是收不到这个被标记关键 cookie,后面的鉴权处理就好办了。这一切都不须要作 token 生命周期的管理,也不用担忧 Referer 会丢失或被中途被篡改。异步

SameSite 的应用

SameStie 有两个值:Strict 和 Lax:工具

SameSite=Strict

严格模式,使用 SameSite=Strict 去标记的 cookie 在任何状况下(包括异步请求和同步请求) 都不能做为第三方 cookie。fetch

SameSite=Lax

宽松模式,使用 SameSite=Lax 去标记的 cookie 在异步请求 和 form 提交跳转的状况下 都不能做为第三方 cookie。jsonp

如今给 b.com 的 cookie bbb1 设置一波看看效果。网站

document.cookie="bbb1=1; SameSite=Strict";
document.cookie="bbb2=2; SameSite=Lax";
document.cookie="bbb3=3;";

注:为了代码简洁,这里就再也不设置 domain,path,expires 什么的了。

设置完毕后,立刻打开 Chrome 调试面板看看 cookie:

clipboard.png

咱们能够看到这里 cookie bbb1 的 SameSite 一列被设置了 Strict,bbb2 被设置了 Lax ,说明设置成功了。
在 a.com 页面中试着异步请求 b.com

// a.html
<img src="http://www.b.com" />

打开宇宙最强抓包工具 whistle 抓包看看 bbb1 和 bbb2 有没有被带到 b.com
clipboard.png

咱们能够看到 bbb1 和 bbb2 没有被带到 b.com ,只看到了 bbb3,很完美。

再看看同步请求:
这里在 a.com 页面上写了一个 <a> 标签。

// a.html
<a href="http://www.b.com"> open b.com </a>

clipboard.png

经过抓包结果咱们能够看到 bbb2 被 设置了 SameSite=Lax 后,在同步请求的方式下,是能够把 cookie bbb2 带到 b.com 的,而 bbb1 依然没有被带上。

Strict or Lax ?

那么问题来了,两种模式咱们应该分别在什么场景下使用呢?

  • 登陆态关键的 cookie 均可以设置为 Strict。
  • 后台根据用户的登陆态动态新建一个能够用于校验登陆态的 cookie ,设置为 Lax ,这样的话对外推广好比微博什么的,你但愿用户在微博上打开你的连接还能保持登陆态。
  • 若是你的页面有可能被第三方网站去 iframe 或 有接口须要作 jsonp ,那么都不能设置 Strict 或 Lax。
相关文章
相关标签/搜索