zoukankan      html  css  js  c++  java
  • CSRF 1 (转)

    一.CSRF是什么?

      CSRF(Cross-site request forgery),中文名称:跨站请求伪造,也被称为:one click attack/session riding,缩写为:CSRF/XSRF。

    二.CSRF可以做什么?

      你这可以这么理解CSRF攻击:攻击者盗用了你的身份,以你的名义发送恶意请求。CSRF能够做的事情包括:以你名义发送邮件,发消息,盗取你的账号,甚至于购买商品,虚拟货币转账......造成的问题包括:个人隐私泄露以及财产安全。

    三.CSRF的原理

    要完成一次CSRF攻击,受害者必须依次完成两个步骤:

      1.登录受信任网站A,并在本地生成Cookie。

      2.在不登出A的情况下,访问危险网站B。

    示例1:

      银行网站A,它以GET请求来完成银行转账的操作,如:http://www.mybank.com/Transfer.php?toBankId=11&money=1000

    危险网站B,它里面有一段HTML的代码如下:<img src=http://www.mybank.com/Transfer.php?toBankId=11&money=1000>

    首先,你登录了银行网站A,然后访问危险网站B,噢,这时你会发现你的银行账户少了1000块......为什么会这样呢?原因是银行网站A违反了HTTP规范,使用GET请求更新资源。

    示例2:

      为了杜绝上面的问题,银行决定改用POST请求完成转账操作。

    银行网站A的WEB表单如下:

    <form action="Transfer.php" method="POST">
        <p>ToBankId: <input type="text" name="toBankId" /></p>
        <p>Money: <input type="text" name="money" /></p>
        <p><input type="submit" value="Transfer" /></p>
      </form>

    后台处理页面Transfer.php如下:

    <?php
        session_start();
        if (isset($_REQUEST['toBankId'] && isset($_REQUEST['money']))
        {
            buy_stocks($_REQUEST['toBankId'], $_REQUEST['money']);
        }
      ?>

    危险网站B,仍然只是包含那句HTML代码:

    <img src=http://www.mybank.com/Transfer.php?toBankId=11&money=1000>

    ,你首先登录了银行网站A,然后访问危险网站B,结果.....和示例1一样,你再次没了1000块~T_T,事故的原因是:银行后台使用了$_REQUEST去获取请求的数据,而$_REQUEST既可以获取GET请求的数据,也可以获取POST请求的数据,这就造成了在后台处理程序无法区分这到底是GET请求的数据还是POST请求的数据。在PHP中,可以使用$_GET和$_POST分别获取GET请求和POST请求的数据。在JAVA中,用于获取请求数据request一样存在不能区分GET请求数据和POST数据的问题。;

    示例3:

      经过前面2个惨痛的教训,银行决定把获取请求数据的方法也改了,改用$_POST,只获取POST请求的数据,后台处理页面Transfer.php代码如下:

    <?php
        session_start();
        if (isset($_POST['toBankId'] && isset($_POST['money']))
        {
            buy_stocks($_POST['toBankId'], $_POST['money']);
        }
      ?>

    复制代码然而,危险网站B与时俱进,它改了一下代码:
    <html>
      <head>
        <script type="text/javascript">
          function steal()
          {
                   iframe = document.frames["steal"];
                   iframe.document.Submit("transfer");
          }
        </script>
      </head>

      <body onload="steal()">
        <iframe name="steal" display="none">
          <form method="POST" name="transfer" action="http://www.myBank.com/Transfer.php">
            <input type="hidden" name="toBankId" value="11">
            <input type="hidden" name="money" value="1000">
          </form>
        </iframe>
      </body>
    </html>
    如果用户仍是继续上面的操作,很不幸,结果将会是再次不见1000块......因为这里危险网站B暗地里发送了POST请求到银行!
    总结一下上面3个例子,CSRF主要的攻击模式基本上是以上的3种,其中以第1,2种最为严重,因为触发条件很简单,一个<img>就可以了,而第3种比较麻烦,需要使用JavaScript,所以使用的机会会比前面的少很多,但无论是哪种情况,只要触发了CSRF攻击,后果都有可能很严重。
    理解上面的3种攻击模式,其实可以看出,CSRF攻击是源于WEB的隐式身份验证机制!WEB的身份验证机制虽然可以保证一个请求是来自于某个用户的浏览器,但却无法保证该请求是用户批准发送的!

    四.CSRF的防御

      我总结了一下看到的资料,CSRF的防御可以从服务端和客户端两方面着手,防御效果是从服务端着手效果比较好,现在一般的CSRF防御也都在服务端进行。

    1.服务端进行CSRF防御

      服务端的CSRF方式方法很多样,但总的思想都是一致的,就是在客户端页面增加伪随机数。

      (1).Cookie Hashing(所有表单都包含同一个伪随机值):

    这可能是最简单的解决方案了,因为攻击者不能获得第三方的Cookie(理论上),所以表单中的数据也就构造失败了:>

    <?php
        //构造加密的Cookie信息
        $value = “DefenseSCRF”;
        setcookie(”cookie”, $value, time()+3600);
      ?>

    在表单里增加Hash值,以认证这确实是用户发送的请求。

    <?php
        $hash = md5($_COOKIE['cookie']);
      ?>
      <form method=”POST” action=”transfer.php”>
        <input type=”text” name=”toBankId”>
        <input type=”text” name=”money”>
        <input type=”hidden” name=”hash” value=”<?=$hash;?>”>
        <input type=”submit” name=”submit” value=”Submit”>
      </form>

    然后在服务器端进行Hash值验证

     <?php
            if(isset($_POST['check'])) {
                 $hash = md5($_COOKIE['cookie']);
                 if($_POST['check'] == $hash) {
                      doJob();
                 } else {
            //...
                 }
            } else {
          //...
            }
          ?>

    这个方法个人觉得已经可以杜绝99%的CSRF攻击了,那还有1%呢....由于用户的Cookie很容易由于网站的XSS漏洞而被盗取,这就另外的1%。一般的攻击者看到有需要算Hash值,基本都会放弃了,某些除外,所以如果需要100%的杜绝,这个不是最好的方法。

  • 相关阅读:
    剑指 Offer——13. 调整数组顺序使奇数位于偶数前面
    剑指 Offer——3. 从尾到头打印链表
    剑指 Offer——2. 替换空格
    剑指 Offer——1. 二维数组中的查找
    LeetCode 905. Sort Array By Parity 按奇偶校验排列数组
    LeetCode 448. Find All Numbers Disappeared in an Array找到所有数组中消失的元素
    SSH 代码笔记
    anaconda3安装caffe
    opencv多版本安装
    人脸文章与数据库
  • 原文地址:https://www.cnblogs.com/lhq8998/p/7295435.html
Copyright © 2011-2022 走看看