Day15-守护饼乾大作战(二)

前言

昨天讲了 Secure 跟 HttpOnly 之後,今天要讲的 SameSite 是一个比较复杂的 cookie 属性,需要花比较多时间讲,所以我们二话不说马上开始吧!

CSRF

在讲 SameSite 之前,这边要先来谈谈什麽是 CSRF 攻击:

事情是这样的,假设你有一个猪猪银行的网路银行帐号,只要你用浏览器上他们网站登入後,就可以进行转帐、买卖外币等等操作。而这个猪猪银行的网站也会在你登入时放一个识别用的 session cookie 到你的浏览器里面,假设那个 cookie 长这样:Set-Cookie: id=123aaa; Domain=pigbank.com; Secure

因为猪猪银行设定这个 cookie 不会马上过期,如果当你的浏览器中有这个 cookie 时,你不小心去到一个很坏很坏的网站 badguy.com,这个网站里面刚好有一个表单长这样

<form action="https://pigbank.com/transfer" method="POST">
    <input type="hidden" name="acct" value="badguy"/>   <!-- 隐藏栏位 -->
    <input type="hidden" name="amount" value="10000"/>  <!-- 隐藏栏位 -->
    <input type="submit" value="免费注册"/>              <!-- 注册按钮 -->
</form>

那在你按下「免费注册」的按钮时,网页就会发送一个请求给 https://pigbank.com/transfer 要求转帐,而且因为你刚刚曾经登入过猪猪银行,因此这个请求会带着 Cookie: id=123aaa; Domain=pigbank.com 一起出去,以你的名义进行转帐。而猪猪银行的 API Server 看到这个请求後,因为 cookie 看起来也没什麽问题,所以他就会以为是你本人登入在操作,於是就真的把你的一万块转给 bad guy 了

以上就是 CSRF 攻击的原理,简单来说他就是利用浏览器会自动带上 cookie 的机制,趁你的 cookie 还在时偷偷发出伪造请求。而 API Server 那边因为看到 cookie 就以为是本人,所以就被伪造请求骗过去

SameSite

从上面的案例可以看出来,CSRF 的根本问题在於浏览器发送请求时会自动带上 cookie,所以 SameSite 属性为了解决 CSRF,就是要将自动送出 cookie 的条件变得更严苛

因为 SameSite 总共有 Strict、Lax、None 三个值可以设定,这边就从最严格的 Strict 开始讲起

  • SameSite=Strict

    所谓的 SameSite=Strict 就是指这个 cookie 只有在自己的网站上才会被发送出去,因此如果猪猪银行设定的是 Set-Cookie: id=123aaa; SameSite=Strict; Secure,那就只有当使用者在操作猪猪银行网站时,这个 cookie 才会被带上。若是你在别人的网站上点到恶意的按钮,不小心发了 POST 请求到 https://pigbank.com/transfer,那就不会带上 cookie

    因为设定了 SameSite=Strict 之後可以防止 cookie 在其他网站上被发送出去,也就完全避免了 CSRF 攻击

  • SameSite=Lax

    虽然使用 SameSite=Strict 可以达到最高的安全性,但完全禁止 cookie 在其他网站上被发送出去有点太严格了,有些服务(譬如说 Facebook 登入)为了知道使用者的状态,他一定得在你写的网站上把他自己的 cookie 送出去,因此他们就不会帮自家的 cookie 设定 SameSite=Strict,取而代之的是 SameSite=Lax

    相较於 Strict 的完全禁止,Lax 允许你在页面跳转到其他网域时顺便把该网域的 cookie 送出去,听起来有点抽象对吧?譬如说我们在按下「Sign in with Facebook」时,如果 Facebook 的 cookie 是设定 SameSite=Strict,那 cookie 就不会送出去,也就无法成功使用 Facebook 登入。但因为按下「Sign in with Facebook」时会开启一个新视窗跳转到 Facebook 的网域,所以如果你是设定 SameSite=Lax,Facebook 的 cookie 就会一并被送出去,也就可以成功使用 Facebook 登入~

    Bitmap

    另外值得一提的是,因为设定成 Lax 可以兼顾方便性跟安全性,所以这两年来很多浏览器如 Chrome、Firefox 都把 SameSite 预设值设为 Lax,即便很多网站没有特别指定 Cookie 的 SameSite 属性,浏览器也可以藉此帮他们提升安全性

  • SameSite=None

    最後就是 SameSite=None,所谓的 None 就是没有XD,所以我们上面讲的那些防护功能他通通都没有,对 CSRF 的防护力当然也是零

    虽然还是有少数情况真的会需要用到 None 来突破 Lax 的限制,但除非你做的是像 GA 这种三不五时就要从别人的网站把 cookie 送回 Google 的服务,否则绝大多数时候你都不会需要 None,就放心的用 Lax 就好了

小结

今天介绍了鼎鼎大名的 CSRF 攻击,以及用来对付他的 SameSite 属性,今天的内容比较复杂一点,如果有哪边不是很理解的欢迎在下方留言问我,我都会尽力回答大家的。如果没问题的话,那明天就要来讲讲要怎麽在 API Server 设定 cookie 的属性,算是相对比较轻松的内容~


<<:  Day15看鱿鱼游戏就要搭上鱿鱼料理-琉球菜鱿鱼小封

>>:  Unity自主学习(十六):认识Unity介面(7)

【Day19-颜色】眼前的黑不是黑,你说的白是什麽白?——浅谈图片资料的色彩空间

在经过了文字和声音的章节,今天终於到了图片的进度 我们会从人类对视觉的认知方式出发,以及谈一下那些不...

热情,是唯一答案

你还记得,前一次是什麽时候以及因为什麽,让你主动不眠不休,一心就想要把它完成,完成时不管别人的眼光,...

Day17 CSS Media Query

在了解Media Queries的用法之前,先来了解一些RWD的观念吧。 RWD是什麽? RWD是...

自动化测试,让你上班拥有一杯咖啡的时间 | Day 14 - 取得 ESLint 支援

此系列文章会同步发文到个人部落格,有兴趣的读者可以前往观看喔。 今天要跟大家分享在 cypress...

TailwindCSS 从零开始 - 增加 Base 样式

什麽是 Base 样式 概念有点像是 CSSreset,现在网页基本上都会使用 CSS reset...