手绘10张图,把CSRF跨域攻击、JWT跨域认证说得明明白白的


手绘10张图,把CSRF跨域攻击、JWT跨域认证说得明明白白的

文章插图
作者 | 写代码的明哥
来源 | Python编程时光
这篇文章本应该是属于 HTTP 里的一部分内容,但是我看内容也挺多的,就单独划分一篇文章来讲下 。
手绘10张图,把CSRF跨域攻击、JWT跨域认证说得明明白白的

文章插图
手绘10张图,把CSRF跨域攻击、JWT跨域认证说得明明白白的

文章插图
什么是跨域请求
要明白什么叫跨域请求,首先得知道什么叫域 。
域,是指由 协议+域名+端口号组成的一个虚拟概念 。
手绘10张图,把CSRF跨域攻击、JWT跨域认证说得明明白白的

文章插图
如果两个域的协议、域名、端口号都一样,就称他们为同域,但是只要有其中一个不一样,就不是同域 。
那么 跨域请求又是什么意思呢?
简单来说,就是在一个域内请求了另一个域的资源,由于域不一致,会有安全隐患 。
 
跨域请求的安全隐患有一个词,叫 CSRF (Cross-site request forgery)攻击,中文名是 跨站请求伪造
简单来说呢,就是攻击者盗用了你的身份,以你的名义发送恶意请求,它能做的坏事有很多,比如以你的名义发邮件,发消息,购物,盗取帐号等 。
CSRF 的实际工作原理是怎样的?
比如现在有两个网站,A 网站是真实受信息的网站,而 B网站是危险网站 。
当你登陆 A 网站后,浏览器会存储 A 网站服务器给你生成的 sessionid 存入 cookie,有了这个 cookie ,就拥有了你的帐号权限,以后请求资料,就不用再次登陆啦 。
对于真实用户来说,是便利,可对于攻击者来说,却是可乘之机 。
手绘10张图,把CSRF跨域攻击、JWT跨域认证说得明明白白的

文章插图
他们可以使用各种社工学引导你点击他们的链接/网站,然后利用你的浏览器上存储的 cookie ,然后在自己的 网站B 发起对 网站A 的请求,获取一些隐私信息,做一些侵害用户权益的事情 。这便是一个完整的 CSRF 攻击 。
 
跨域请求的安全防御完成一次完整的 CSRF 攻击,只要两个步骤:
  1. 登录受信任网站A,并本地已经存储了 Cookie
  2. 在不登出A的情况下,访问危险网站B,网站 B 诱导你发 A 发请求 。
很多浏览器用户对于网络安全是无意识的,因此我们不能指望通过规范用户行为来避免CSRF攻击 。
那如何从技术手段规避一定的 CSRF 攻击的风险呢?
  1. 利用浏览器的同源策略:最基础的安全策略
  2. 对请求的来源进行验证:Referer Check
  3. 使用验证码强制使用户进行交互确认,保证请求是用户发起
  4. CSRF Token,注意不要使用 cookie 来存储token
  5. JSON Web Token
以上是我知道的历史上用来抵御 CSRF 攻击的方法
  • 有的虽然实现简单,但是不够安全
  • 有的虽然安全,但是用户体验不好
  • 有的虽然安全,用户体验好,但是有缺点
具体应该选哪一种呢,不妨继续往下看 。
 
3.1 同源策略浏览器上有一个同源策略(SOP,全称 Same origin policy),它会在一定程度上禁止这种跨域请求的发生 。
但同源策略是最基本的安全策略,对于低级的 CSRF 攻击 ,它是很有效果的 。
可以说 Web 是构建在同源策略基础之上的,浏览器只是针对同源策略的一种实现 。
同源策略在提升了 Web前端的安全性的同时,也牺牲了Web拓展上的灵活性 。
设想若把html、js、css、flash,image等文件全部布置在一台服务器上,小网站这样凑活还行,大中网站如果这样做服务器根本受不了的,因此同源策略,就像是双刃剑 。不过这些都是有解的 。
 
3.2 Referer Check在 HTTP 协议中,有一个字段叫做 Referer,它记录了HTTP 请求的来源地址 。
当发生 CSRF 攻击时,这个来源地址,会变成危险网站 B,因此只要在服务端校验这个 Referer 是不是和自己同一个域就可以判断这个请求是跨站请求 。
手绘10张图,把CSRF跨域攻击、JWT跨域认证说得明明白白的

文章插图
但这种方法,也是有局限性的,在一些非主流的浏览器,或者使用了那些非常古老的浏览器版本,这个 Referer 字段,是有可能会被篡改的 。
退一步讲,假设你使用了最安全的最新版本的浏览器,这个值无法被篡改,依旧还是有安全隐患 。
因为有些用户出于某些隐私考虑,会在浏览器设置关闭这个 Referer 字段,也有的网站会使用一些技术手段使用请求不携带 Referer 字段 。


推荐阅读