前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >关于防CSRF你需要了解的另一种方法

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

作者头像
IMWeb前端团队
发布2019-12-03 17:40:57
5730
发布2019-12-03 17:40:57
举报
文章被收录于专栏:IMWeb前端团队

本文作者:IMWeb zzbozheng 原文出处:IMWeb社区 未经同意,禁止转载

前言

网站通常会使用 cookie来记录用户的登录状态,但并非安全,因为 cookie被允许在第三方网站(也不仅限于第三方)发起的请求中携带,因此利用这一点可以达到 CSRF 攻击。本文不再对 CSRF 的原理作过多阐述,点击这里了解CSRF 。 如果别人问起防 CSRF 的方法有哪些,大家通常会说出:Token + Referer,该方案在业界已经非常成熟。当一个问题有了解决办法后,就很人有人会去了解别的方案,我想听听不同的声音。

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

本文给大家介绍另一种防 CSRF 的方法。

第三方请求

开始前我们先了解一下第三方请求,什么样的请求被称为第三方请求?简单来说就是在一个网页上发起一个不同源的请求,那么我们可以称为第三方请求。

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

第三方cookie

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

关于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。

SameSite=Lax

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

现在给 b.com 的 cookie bbb1 设置一波看看效果。

代码语言:javascript
复制
document.cookie="bbb1=1; SameSite=Strict";
document.cookie="bbb2=2; SameSite=Lax";
document.cookie="bbb3=3;";

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

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

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

代码语言:javascript
复制
// a.html
<img src="http://www.b.com" />

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

我们可以看到 bbb1 和 bbb2 没有被带到 b.com ,只看到了 bbb3,很完美。

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

代码语言:javascript
复制
// a.html
<a href="http://www.b.com"> open b.com </a>

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

Strict or Lax ?

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

  • 登录态关键的 cookie都可以设置为 Strict。
  • 后台根据用户的登录态动态新建一个可以用于校验登录态的 cookie,设置为 Lax ,这样的话对外推广比如微博什么的,你希望用户在微博上打开你的链接还能保持登录态。
  • 如果你的页面有可能被第三方网站去 iframe 或 有接口需要做 jsonp ,那么都不能设置 Strict 或 Lax。
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2018-09-01 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 第三方请求
  • 第三方cookie
  • 关于SameSite
  • SameSite 的应用
    • SameSite=Strict
      • SameSite=Lax
      • Strict or Lax ?
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档