CSRF问题

防御CSRF攻击的策略

目前防御 CSRF 攻击有以下四种策略(不全)

  • 验证 HTTP Referer 字段
  • 在请求地址中添加 token 并验证
  • 在 HTTP 头中自定义属性并验证
  • 验证码

(1)验证 HTTP Referer 字段
HTTP头中存在Refer 字段标记了请求的源地址,通过校验该字段可以检验是否为钓鱼网站的请求
优点:简单易行
缺陷:安全性不高,可能影响用户正常使用(Refer值由浏览器提供,实际上目前已经有一些方法可以篡改特定浏览器的Refer值,比如IE6和FF2;另外有些用户出于隐私考虑可能设置浏览器不提供Refer,可能导致误判为CSRF攻击)

(2)在请求地址中添加token并验证
登录时随机生成一个token,并存入session中,之后的请求需要将token在请求地址中带上,后端检验是否与session中的token相等
优点:比第一种方法具有更高的安全性
缺陷:对于动态生成的html代码无法使用js动态加入token,而需要在编码时手动加入;难以保证token本身的安全,比如论坛等,黑客可以发布自己的网址,服务器也会给它加上token,以此获得token的值(系统可以判断是否为本站地址来选择是否给请求带上token),不过,即使这个 csrftoken 不以参数的形式附加在请求之中,黑客的网站也同样可以通过 Referer 来得到这个 token 值以发动 CSRF 攻击,这也是一些用户喜欢手动关闭浏览器 Referer 功能的原因。
举例:
令牌生成函数(gen_token())

      function  gen_token() {
      //这里我是贪方便,实际上单使用Rand()得出的随机数作为令牌,也是不安全的。
    //这个可以参考我写的Findbugs笔记中的《Random object created and used only once》
           $token   =   md5 ( uniqid ( rand () ,   true ));
           return   $token ;
     }

Session令牌生成函数(gen_stoken())

      <? php
        function  gen_stoken() {
       $pToken = "" ;
      if( $_SESSION [STOKEN_NAME]  ==  $pToken ){
        //没有值,赋新值
         $_SESSION [STOKEN_NAME]  =   gen_token() ;
      }    
      else{
        //继续使用旧的值
      }
       }
      ?>

WEB表单生成隐藏输入域的函数

     <?php
       function gen_input() {
            gen_stoken();
            echo<input type=\”hidden\” name=\”" . FTOKEN_NAME . “\”
                 value=\”" . $_SESSION[STOKEN_NAME] . “\”>;
       }
     ?>

WEB表单结构

      <? php
           session_start ();
           include (”functions . php”);
      ?>
      < form method =POST” action = ”transfer . php” >
           < input type = ”text” name = ”toBankId” >
           < input type = ”text” name = ”money” >
           <?  gen_input();  ?>
           < input type = ”submit” name = ”submit” value = ”Submit” >
      </ FORM >

最后服务端核对令牌

(3)服在 HTTP 头中自定义属性并验证
和上一种方法类似,不同的是将token作为参数放在HTTP头中的自定义属性中,可以通过XMLHttpRequest类给所有请求加上csrftoken这个Http头属性,并存入token数值
缺陷:这种方法的局限性非常大。XMLHttpRequest 请求通常用于 Ajax 方法中对于页面局部的异步刷新,并非所有的请求都适合用这个类来发起,而且通过该类请求得到的页面不能被浏览器所记录下,从而进行前进,后退,刷新,收藏等操作,给用户带来不便。另外,对于没有进行 CSRF 防护的遗留系统来说,要采用这种方法来进行防护,要把所有请求都改为 XMLHttpRequest 请求,这样几乎是要重写整个网站,这代价无疑是不能接受的。

(4)验证码略

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值