CSRF攻击与防御

阅读目录

回到顶部

1、简介

  CSRF的全名为Cross-site request forgery,它的中文名为 跨站请求伪造(伪造跨站请求【这样读顺口一点】)

  CSRF是一种夹持用户在已经登陆的web应用程序上执行非本意的操作的攻击方式。相比于XSS,CSRF是利用了系统对页面浏览器的信任,XSS则利用了系统对用户的信任。

回到顶部

2、CSRF攻击原理

下面为CSRF攻击原理图:

由上图分析我们可以知道构成CSRF攻击是有条件的:

  1、客户端必须一个网站并生成cookie凭证存储在浏览器中

  2、该cookie没有清除,客户端又tab一个页面进行访问别的网站

回到顶部

3、CSRF例子与分析

  我们就以游戏虚拟币转账为例子进行分析

回到顶部

  3.1、简单级别CSRF攻击

  假设某游戏网站的虚拟币转账是采用GET方式进行操作的,样式如:

1 http://www.game.com/Transfer.php?toUserId=11&vMoney=1000

  此时恶意攻击者的网站也构建一个相似的链接:

  1、可以是采用图片隐藏,页面一打开就自动进行访问第三方文章:<img src=‘攻击链接‘>

  2、也可以采用js进行相应的操作

http://www.game.com/Transfer.php?toUserId=20&vMoney=1000         #toUserID为攻击的账号ID

  1、假若客户端已经验证并登陆www.game.com网站,此时客户端浏览器保存了游戏网站的验证cookie

  2、客户端再tab另一个页面进行访问恶意攻击者的网站,并从恶意攻击者的网站构造的链接来访问游戏网站

  3、浏览器将会携带该游戏网站的cookie进行访问,刷一下就没了1000游戏虚拟币

回到顶部

  3.2、中级别CSRF攻击

  游戏网站负责人认识到了有被攻击的漏洞,将进行升级改进。

  将由链接GET提交数据改成了表单提交数据

//提交数据表单<form action="./Transfer.php" method="POST">
    <p>toUserId: <input type="text" name="toUserId" /</p>
    <p>vMoney: <input type="text" name="vMoney" /></p>
    <p><input type="submit" value="Transfer" /></p>
</form>

  Transfer.php

1 <?php
2      session_start();
3      if (isset($_REQUEST[‘toUserId‘] && isset($_REQUEST[‘vMoney‘]))  #验证
4      {
5           //相应的转账操作
6      }
7  ?>

  恶意攻击者将会观察网站的表单形式,并进行相应的测试。

  首先恶意攻击者采用(http://www.game.com/Transfer.php?toUserId=20&vMoney=1000)进行测试,发现仍然可以转账。

  那么此时游戏网站所做的更改没起到任何的防范作用,恶意攻击者只需要像上面那样进行攻击即可达到目的。

  总结:

  1、网站开发者的错误点在于没有使用$_POST进行接收数据。当$_REQUEST可以接收POST和GET发来的数据,因此漏洞就产生了。

回到顶部

  3.3、高级别CSRF攻击

  这一次,游戏网站开发者又再一次认识到了错误,将进行下一步的改进与升级,将采用POST来接收数据

  Transfer.php

1 <?php
2      session_start();
3      if (isset($_POST[‘toUserId‘] && isset($_POST[‘vMoney‘]))  #验证
4      {
5           //相应的转账操作
6      }
7  ?>

  此时恶意攻击者就没有办法进行攻击了么?那是不可能的。

  恶意攻击者根据游戏虚拟币转账表单进行伪造了一份一模一样的转账表单,并且嵌入到iframe中

嵌套页面:(用户访问恶意攻击者主机的页面,即tab的新页面)

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>攻击者主机页面</title>
    <script type="text/javascript">
    function csrf()
    {
        window.frames[‘steal‘].document.forms[0].submit();
    }
    </script>
</head>
<body >
<iframe name="steal" display="none" src="./xsrf.html">
</iframe>
</body>
</html>

表单页面:(csrf.html)

<!DOCTYPE html>
<html>
<head>
    <title>csrf</title>
</head>
<body>
<form display="none" action="http://www.game.com/Transfer.php" method="post" >
    <input type="hidden" name="toUserID" value="20">
    <input type="hidden" name="vMoney" value="1000">
</form>
</body>
</html>

  客户端访问恶意攻击者的页面一样会遭受攻击。

总结:

  CSRF攻击是源于Web的隐式身份验证机制!Web的身份验证机制虽然可以保证一个请求是来自于某个用户的浏览器,但却无法保证该请求是用户批准发送的

回到顶部

4、CSRF防御方法

  服务器端防御:

  1、重要数据交互采用POST进行接收,当然是用POST也不是万能的,伪造一个form表单即可破解

  2、使用验证码,只要是涉及到数据交互就先进行验证码验证,这个方法可以完全解决CSRF。但是出于用户体验考虑,网站不能给所有的操作都加上验证码。因此验证码只能作为一种辅助手段,不能作为主要解决方案。

  3、验证HTTP Referer字段,该字段记录了此次HTTP请求的来源地址,最常见的应用是图片防盗链。PHP中可以采用APache URL重写规则进行防御,可参考:http://www.cnblogs.com/phpstudy2015-6/p/6715892.html

  4、为每个表单添加令牌token并验证

(可以使用cookie或者session进行构造。当然这个token仅仅只是针对CSRF攻击,在这前提需要解决好XSS攻击,否则这里也将会是白忙一场【XSS可以偷取客户端的cookie】)

  CSRF攻击之所以能够成功,是因为攻击者可以伪造用户的请求,该请求中所有的用户验证信息都存在于Cookie中,因此攻击者可以在不知道这些验证信息的情况下直接利用用户自己的Cookie来通过安全验证。由此可知,抵御CSRF攻击的关键在于:在请求中放入攻击者所不能伪造的信息,并且该信息不存在于Cookie之中。

  鉴于此,我们将为每一个表单生成一个随机数秘钥,并在服务器端建立一个拦截器来验证这个token,如果请求中没有token或者token内容不正确,则认为可能是CSRF攻击而拒绝该请求。

  由于这个token是随机不可预测的并且是隐藏看不见的,因此恶意攻击者就不能够伪造这个表单进行CSRF攻击了。

  要求:

  1、要确保同一页面中每个表单都含有自己唯一的令牌

  2、验证后需要删除相应的随机数

构造令牌类Token.calss.php

 1 <?php
 2 class Token
 3 {
 4     /**
 5     * @desc 获取随机数
 6     *
 7     * @return string 返回随机数字符串
 8     */
 9     private function getTokenValue()
10     {
11         return md5(uniqid(rand(), true).time());
12     }
13
14     /**
15     * @desc 获取秘钥
16     *
17     * @param $tokenName string | 与秘钥值配对成键值对存入session中(标识符,保证唯一性)
18     *
19     * @return array 返回存储在session中秘钥值
20     */
21     public function getToken($tokenName)
22     {
23         $token[‘name‘]=$tokenName;      #先将$tokenName放入数组中
24         session_start();
25         if(@$_SESSION[$tokenName])      #判断该用户是否存储了该session
26         {                               #是,则直接返回已经存储的秘钥
27             $token[‘value‘]=$_SESSION[$tokenName];
28             return $token;
29         }
30         else                            #否,则生成秘钥并保存
31         {
32             $token[‘value‘]=$this->getTokenValue();
33             $_SESSION[$tokenName]=$token[‘value‘];
34             return $token;
35         }
36     }
37
38 }
39 #测试
40 $csrf=new Token();
41 $name=‘form1‘;
42 $a=$csrf->getToken($name);
43 echo "<pre>";
44 print_r($a);
45 echo "</pre>";
46 echo "<pre>";
47 print_r($_SESSION);
48 echo "</pre>";die;
49
50 ?> 

表单中使用:

 1 <?php
 2           session_start();
 3           include(”Token.class.php”);
 4           $token=new Token();
 5           $arr=$token->getToken(‘transfer’);    #保证唯一性(标识符)
 6 ?>
 7  <form method=”POST” action=”./transfer.php”>
 8           <input type=”text” name=”toUserId”>
 9           <input type=”text” name=”vMoney”>
10           <input type="hidden" name="<?php echo $arr[‘name‘] ?>"  value="<?php echo $arr[‘value‘]?>" >
11           <input type=”submit” name=”submit” value=”Submit”>
12  </from>

验证:

 1 <?php
 2 #转账表单验证
 3 session_start();
 4 if($_POST[‘transfer‘]==$_SESSION[‘transfer‘])       #先检验秘钥
 5 {
 6     unset($_SESSION[‘transfer‘]);    #删除已经检验的存储秘钥
 7     if ( &&isset($_POST[‘toUserId‘] && isset($_POST[‘vMoney‘]))  #验证
 8     {
 9          //相应的转账操作
10     }
11 }
12 else
13 {
14     return false;
15 }
16 ?>

 1 <?php
 2 #转账表单验证
 3 session_start();
 4 if($_POST[‘transfer‘]==$_SESSION[‘transfer‘])       #先检验秘钥
 5 {
 6     unset($_SESSION[‘transfer‘]);    #删除已经检验的存储秘钥
 7     if ( &&isset($_POST[‘toUserId‘] && isset($_POST[‘vMoney‘]))  #验证
 8     {
 9          //相应的转账操作
10     }
11 }
12 else
13 {
14     return false;
15 }
16 ?>

该方法套路:

1. 用户访问某个表单页面。

2. 服务端生成一个Token,放在用户的Session中,或者浏览器的Cookie中。【这里已经不考虑XSS攻击】

3. 在页面表单附带上Token参数。

4. 用户提交请求后, 服务端验证表单中的Token是否与用户Session(或Cookies)中的Token一致,一致为合法请求,不是则非法请求。

回到顶部

5、参考文献

1. 《浅谈CSRF攻击方式

2. 《Web安全之CSRF攻击

(以上是自己的一些见解,若有不足或者错误的地方请各位指出)

作者:那一叶随风   http://www.cnblogs.com/phpstudy2015-6/

原文地址:http://www.cnblogs.com/phpstudy2015-6/p/6771239.html

声明:本博客文章为原创,只代表本人在工作学习中某一时间内总结的观点或结论。转载时请在文章页面明显位置给出原文链接

时间: 2024-10-05 18:14:40

CSRF攻击与防御的相关文章

CSRF攻击与防御(写得非常好)

转载地址:http://www.phpddt.com/reprint/csrf.html        CSRF概念:CSRF跨站点请求伪造(Cross-Site Request Forgery),跟XSS攻击一样,存在巨大的危害性,你可以这样来理解:       攻击者盗用了你的身份,以你的名义发送恶意请求,对服务器来说这个请求是完全合法的,但是却完成了攻击者所期望的一个操作,比如以你的名义发送邮件.发消息,盗取你的账号,添加系统管理员,甚至于购买商品.虚拟货币转账等. 如下:其中Web A为

CSRF——攻击与防御

CSRF——攻击与防御 author: lake2 0x01 什么是CSRF攻击 CSRF是Cross Site Request Forgery的缩写(也缩写为XSRF),直译过来就是跨站请求伪造的意思,也就是在用户会话下对某个CGI做一些GET/POST的事情——这些事情用户未必知道和愿意做,你能够把它想做HTTP会话劫持.    站点是通过cookie来识别用户的,当用户成功进行身份验证之后浏览器就会得到一个标识其身份的cookie,仅仅要不关闭浏览器或者退出登录,以后訪问这个站点会带上这个

Web安全之CSRF攻击的防御措施

CSRF是什么? Cross Site Request Forgery,中文是:跨站点请求伪造. CSRF攻击者在用户已经登录目标网站之后,诱使用户访问一个攻击页面,利用目标网站对用户的信任,以用户身份在攻击页面对目标网站发起伪造用户操作的请求,达到攻击目的. 举个例子 简单版: 假如博客园有个加关注的GET接口,blogUserGuid参数很明显是关注人Id,如下: http://www.cnblogs.com/mvc/Follow/FollowBlogger.aspx?blogUserGui

CSRF 攻击与防御

转一篇文章,个人感觉写的通俗易懂 http://www.cnblogs.com/hyddd/archive/2009/04/09/1432744.html 一.CSRF是什么? CSRF(Cross-site request forgery),中文名称:跨站请求伪造,也被称为:one click attack/session riding,缩写为:CSRF/XSRF. 二.CSRF可以做什么? 你这可以这么理解CSRF攻击:攻击者盗用了你的身份,以你的名义发送恶意请求.CSRF能够做的事情包括:

CSRF攻击与防御原理

CSRF是什么? (Cross Site Request Forgery, 跨站域请求伪造)是一种网络的攻击方式,它在 2007 年曾被列为互联网 20 大安全隐患之一,也被称为"One Click Attack"或者Session Riding,通常缩写为CSRF或者XSRF,是一种对网站的恶意利用也就是人们所知道的钓鱼网站.尽管听起来像跨站脚本(XSS),但它与XSS非常不同,并且攻击方式几乎相左.XSS利用站点内的信任用户,而CSRF则通过伪装来自受信任用户的请求来利用受信任的网

转-CSRF——攻击与防御

0x01 什么是CSRF攻击 CSRF是Cross Site Request Forgery的缩写(也缩写为XSRF),直译过来就是跨站请求伪造的意思,也就是在用户会话下对某个CGI做一些GET/POST的事情--这些事情用户未必知道和愿意做,你可以把它想做HTTP会话劫持.    网站是通过cookie来识别用户的,当用户成功进行身份验证之后浏览器就会得到一个标识其身份的cookie,只要不关闭浏览器或者退出登录,以后访问这个网站会带上这个cookie.如果这期间浏览器被人控制着请求了这个网站

安全测试 - CSRF攻击及防御

CSRF(Cross-site request forgery跨站请求伪造) 尽管听起来像跨站脚本(XSS),但它与XSS非常不同,并且攻击方式几乎相左.XSS利用站点内的信任用户,而CSRF则通过伪装来自受信任用户的请求来利用受信任的网站. 信任站点A, 恶意站点B, 用户C 攻击流程: 1. 前提: 用户C登录站点A --> 站点A会在用户本地浏览器产生COOKIE 2. 用户C在登录情况下,访问恶意站点B --> B会偷偷发出访问A的请求给用户C 3. 根据B的请求,用户C的浏览器带着c

CSRF攻击与防护讲解

CSRF概念:CSRF跨站点请求伪造(Cross—Site Request Forgery),跟XSS攻击一样,存在巨大的危害性,你可以这样来理解: 攻击者盗用了你的身份,以你的名义发送恶意请求,对服务器来说这个请求是完全合法的,但是却完成了攻击者所期望的一个操作,比如以你的名义发送邮件.发消息,盗取你的账号,添加系统管理员,甚至于购买商品.虚拟货币转账等. 如下:其中Web A为存在CSRF漏洞的网站,Web B为攻击者构建的恶意网站,User C为Web A网站的合法用户.  CSRF攻击攻

CSRF攻击原理以及防御

一.CSRF是什么? CSRF(Cross-site request forgery),中文名称:跨站请求伪造,也被称为:one click attack/session riding,缩写为:CSRF/XSRF. 二.CSRF可以做什么? 你这可以这么理解CSRF攻击:攻击者盗用了你的身份,以你的名义发送恶意请求.CSRF能够做的事情包括:以你名义发送邮件,发消息,盗取你的账号,甚至于购买商品,虚拟货币转账......造成的问题包括:个人隐私泄露以及财产安全. 三.CSRF漏洞现状 CSRF这