csrf攻击点滴

什么是csrf

csrf即跨域请求伪造,在用户未安全退出A站时,攻击者诱导用户点击第三方网站,第三方网站向A站发起请求,此时浏览器当作是用户发起的请求并加上了用户的凭证,而不是第三方请求,A站接受到请求后执行一系列操作,但是此时用户自身并不知情。

特点:

  1. 攻击发生在第三方而不是受攻击的站点,因此很难防御
  2. 在整个过程中,利用受害者在被攻击网站的登陆凭证,冒充受害者提交操作,而不是盗取凭证
  3. 整个过程中,攻击者并不能获取受害者的凭证,冒充受害者的身份
    在这里插入图片描述

产生csrf的原因是什么

  1. 网站相信浏览器
  2. 当用户从第三方网站访问某个信任的站点时,浏览器直接使用已经保存的凭证

csrf攻击方式

  1. Get型csrf

    这种类型比较简单,通常的用法是:

    <img src=http://www.xxx.com/?amount=1000&for=hack>
    

    当用户访问这个第三方页面时,就会自动向信任的站点发起请求

  2. POSTcsrf

    这种类型的利用方式通常为:

    <form action="http://www.xxx.com/" method="POST">
    		<input type="hidden" name="amount" value="1000">
    		<input type="hidden" name="for" value="hack">
    </form>
    <script>
    		document.forms[0].submit();
    </script>
    

    当受害者点击包含上述的代码时就会自动向目标网站发起请求

  3. 链接型
    这种方式不如上面的两种方式好用,上面的都是自动发送请求,但是这种必须要用户点击才可以

    <a href="http://www.xxx.com/?mount=1000&for=hack" target="_blank">...</a>
    

如何防御csrf漏洞

两个重要点:

1. 拒绝不安全的第三方域请求(同源检测 + samesite cookie)
  1. 使得第三方域不能发起正确请求(Token + 验证码 + 双重cookie)
阻止不明外域的访问
  • 同源检测

    HTTP协议中,有两个字段用来标记发起请求的域的名称,originreferer

    • origin

      一般在进行跨域请求的时候,浏览器会在请求头上加入origin 字段,如果在请求头中有这个字段的话,就可以知道请求的来源域。但是origin 字段在一下两种情况下并不存在

    1. IE 11不会在跨域访问的时候加上origin 字段,referer 字段是唯一的判断标准
    2. 302 重定向请求不会在请求头中出现 origin 字段,因为 302 重定向都是将 URL 重定向到新的服务器上面去,而浏览器不想将 origin 泄露到新的服务器上面去
    • referer

      referer 字段记录了当前HTTP请求的来源地址,referer的值是由浏览器提供的,每个浏览器对referer的具体实现是有差异的,所以如果让安全性完全依赖于浏览器的referer值是不安全的,在有些情况下用户可以修改自己的referer或者增加referer字段

      2014年发布的referer policy 规定了五种referer策略
      在这里插入图片描述
      其中的same origin表示同源的网站需要加上referer,不同源的不加上

      设置referer策略有以下几种方式:

    1. CSP中进行设置
    2. html文档首的meta中进行设置
    3. a标签中进行设置,属性名为referrerpolicy

    以下几种情况中没有referer或者referer不可信:

    1. IE 6 or 7window.location.hrefwindow.open,会丢失referer
    2. 在所有浏览器中,HTTPS跳转到HTTP时,referer也会丢失
    3. 点击Flash到达某一个网站时,referer很杂乱,不可信

    一般情况下,如果refererorigin都不存在时,直接对这个网站进行拦截。但是我们不能拦截掉所有的外域的请求,比如说使用百度等搜索引擎时,这种情况下,请求的头部一般是:

    Accept: text/html
    Method: Get
    

    当然,允许这种请求的前提是,GET参数不会引起站点的数据的改变

    虽然说大部分情况下csrf是由第三方站点发起的,但是也有一些是在本域发起的,例如:黑客利用xss漏洞,在本域发表评论等,这个时候仅仅依靠同源机制是不够的

    • Samesite Cookie

      Samesite Cookie属性是set-Cookie的新属性,这个属性标识了这个Cookie是否能够被当作第三方站点的cookie

    Samesite属性有两个属性值,StrictLax

    • Strict

      Set-Cookie: foo=1; Samesite=Strict,这种情况下,通过第三方站点访问本域的时候,不会加上foo

    • Lax

      Set-Cookie: aoo=1; Samesite=Lax,在这种情况下,通过第三方站点访问本域时,如果是GET请求,那么久加上aoo这个值,但是如果是通过POST方法提交数据的话,这个cookie值还是不会被添加进去

附加只有在本域才能获取的信息

这一点是利用了攻击者不能获取cookie的特点

  • CSRF TOKEN 或者验证码
  1. 在用户第一次访问站点时,生成一个Token存放在session中。

  2. 随后用户访问的每一个页面在加载时遍历整棵DOM树,在每个aform标签后都加入Token

  3. 发起请求时,都会带上这个Token

    GET  http://xxx.com?csrf_token=...
    POST  <input type="hidden" name="csrf_token"/>
    
  4. 服务端验证Token值是否正确,验证的时候要看token是否正确以及时间时候过期这两点

    由于攻击者不知道token值,自然就不能伪造请求了,但是站点如果存在xss漏洞的话,就可能导致攻击者盗取到tokenxss+csrf有时候可以产生很大的危害。

  • 双重Cookie

    采用Token的方式会占用大量的内存,双重Cookie的方式会减少内存的占用。双重cookie的校验流程如下:

  1. 前端提取出cookie中的token值,并且把token值加入到URL中,使其变成:http://xxx.com?csrf_token=xxxx
  2. 后端校验csrf_token的值与cookie中的值是否相同,如果相同则接受请求,否则拒绝请求

可以看到这种方式与Token的方法相比简单很多,但是这种方法并没有得到大规模的应用,原因如下:

  1. cookie只在子域的话:如果用户访问的网站为www.a.com,但是后端的网站为api.a.com,那么前端页面是拿不到后端的cookie的(时间顺序不一样),那么就无法完成双重cookie验证
  2. cookie在根域下的话:如果认证cookie被放在a.com下,每个子域都可访问和改变这个值,并且如果某一个子域页面存在漏洞被xss攻击,那么就获取了这个父域的cookie,导致所有的页面陷于危险,并且可以利用xss漏洞自己配置cookie

参考链接:https://juejin.im/post/5bc009996fb9a05d0a055192#heading-30

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值