浅谈CSRF攻击方式

标签: csrf 攻击 | 发表时间:2012-07-18 08:00 | 作者:[email protected] (秩名)
出处:http://www.kuqin.com/jingyan/

酷勤网 � 程序员的那点事!

一.CSRF是什么?

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

二.CSRF可以做什么?

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

三.CSRF漏洞现状

  CSRF这种攻击方式在2000年已经被国外的安全人员提出,但在国内,直到06年才开始被关注,08年,国内外的多个大型社区和交互网站分别爆出CSRF漏洞,如:NYTimes.com(纽约时报)、Metafilter(一个大型的BLOG网站),YouTube和百度HI......而现在,互联网上的许多站点仍对此毫无防备,以至于安全业界称CSRF为“沉睡的巨人”。

四.CSRF的原理

  下图简单阐述了CSRF攻击的思想:

  

  从上图可以看出,要完成一次CSRF攻击,受害者必须依次完成两个步骤:

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

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

  看到这里,你也许会说:“如果我不满足以上两个条件中的一个,我就不会受到CSRF的攻击”。是的,确实如此,但你不能保证以下情况不会发生:

  1.你不能保证你登录了一个网站后,不再打开一个tab页面并访问另外的网站。

  2.你不能保证你关闭浏览器了后,你本地的Cookie立刻过期,你上次的会话已经结束。(事实上,关闭浏览器不能结束一个会话,但大多数人都会错误的认为关闭浏览器就等于退出登录/结束会话了......)

  3.上图中所谓的攻击网站,可能是一个存在其他漏洞的可信任的经常被人访问的网站。

  上面大概地讲了一下CSRF攻击的思想,下面我将用几个例子详细说说具体的CSRF攻击,这里我以一个银行转账的操作作为例子(仅仅是例子,真实的银行网站没这么傻:>)

  示例1:

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

  危险网站B,它里面有一段HTML的代码如下:


Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

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

  首先,你登录了银行网站A,然后访问危险网站B,噢,这时你会发现你的银行账户少了1000块......

  为什么会这样呢?原因是银行网站A违反了HTTP规范,使用GET请求更新资源。在访问危险网站B的之前,你已经登录了银行网站A,而B中的<img>以GET的方式请求第三方资源(这里的第三方就是指银行网站了,原本这是一个合法的请求,但这里被不法分子利用了),所以你的浏览器会带上你的银行网站A的Cookie发出Get请求,去获取资源“http://www.mybank.com/Transfer.php?toBankId=11&money=1000”,结果银行网站服务器收到请求后,认为这是一个更新资源操作(转账操作),所以就立刻进行转账操作......

   示例2:

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

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


Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

-->  <formaction="Transfer.php"method="POST">
    <p>ToBankId:<inputtype="text"name="toBankId"/></p>
    <p>Money:<inputtype="text"name="money"/></p>
    <p><inputtype="submit"value="Transfer"/></p>
  </form>

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

复制代码


Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

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

复制代码

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


Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

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

  和示例1中的操作一样,你首先登录了银行网站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代码如下:

复制代码


Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

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

复制代码

  然而,危险网站B与时俱进,它改了一下代码:

复制代码


Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

--><html>
  <head>
    <scripttype="text/javascript">
      functionsteal()
      {
     iframe=document.frames["steal"];
     iframe.document.Submit("transfer");
      }
    </script>
  </head>

  <bodyonload="steal()">
    <iframename="steal"display="none">
      <formmethod="POST"name="transfer" action="http://www.myBank.com/Transfer.php">
        <inputtype="hidden"name="toBankId"value="11">
        <inputtype="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(理论上),所以表单中的数据也就构造失败了:>


Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

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

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

复制代码


Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

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

复制代码

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

复制代码


Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

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

复制代码

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

  这个方案的思路是:每次的用户提交都需要用户在表单中填写一个图片上的随机字符串,厄....这个方案可以完全解决CSRF,但个人觉得在易用性方面似乎不是太好,还有听闻是验证码图片的使用涉及了一个被称为MHTML的Bug,可能在某些版本的微软IE中受影响。

  (3).One-Time Tokens(不同的表单包含一个不同的伪随机值)

  在实现One-Time Tokens时,需要注意一点:就是“并行会话的兼容”。如果用户在一个站点上同时打开了两个不同的表单,CSRF保护措施不应该影响到他对任何表单的提交。考虑一下如果每次表单被装入时站点生成一个伪随机值来覆盖以前的伪随机值将会发生什么情况:用户只能成功地提交他最后打开的表单,因为所有其他的表单都含有非法的伪随机值。必须小心操作以确保CSRF保护措施不会影响选项卡式的浏览或者利用多个浏览器窗口浏览一个站点。

  以下我的实现:

  1).先是令牌生成函数(gen_token()):

复制代码


Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

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

复制代码

  2).然后是Session令牌生成函数(gen_stoken()):

复制代码


Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

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

复制代码

  3).WEB表单生成隐藏输入域的函数:

复制代码


Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

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

复制代码

  4).WEB表单结构:

复制代码

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

复制代码

  5).服务端核对令牌:

  这个很简单,这里就不再�铝恕�/p>

  上面这个其实不完全符合“并行会话的兼容”的规则,大家可以在此基础上修改。

  其实还有很多想写,无奈精力有限,暂且打住,日后补充,如果错漏,请指出:>

  PS:今天下午写这篇文档的时候FF崩溃了一次,写了一半文章的全没了,郁闷好久T_T.......

  转载请说明出处,谢谢[hyddd(http://www.cnblogs.com/hyddd/)]

六.参考文献

[1]. Preventing CSRF

[2]. Security Corner: Cross-Site Request Forgeries

[3]. 《深入解析跨站请求伪造漏洞:原理剖析》

[4]. 《Web安全测试之跨站请求伪造(CSRF)》

[5]. 《深入解析跨站请求伪造漏洞:实例讲解》

[6].http://baike.baidu.com/view/1609487.htm

正在加载推荐文章
常见的 XSS 注入攻击方式 Part.1
黑帽与Defcon大会中的十大最具威胁攻击方式
防ARP攻击办法
  • 默认表情
  • 阿狸
发  布
  或游客留言 社会化登录:
  • 默认表情
  • 阿狸
回  复
  或游客留言 社会化登录:
www.kuqin.com
数据正在加载中...
无觅相关文章插件,快速提升流量

[ comments ]

相关 [csrf 攻击] 推荐:

浅谈CSRF攻击方式

- - 酷勤网-挖经验 [expanded by feedex.net]
酷勤网 � 程序员的那点事.   CSRF(Cross-site request forgery),中文名称:跨站请求伪造,也被称为:one click attack/session riding,缩写为:CSRF/XSRF.   你这可以这么理解CSRF攻击:攻击者盗用了你的身份,以你的名义发送恶意请求.

CSRF 攻击的应对之道

- - 互联网 - ITeye博客
CSRF 攻击的应对之道. 牛 刚, 软件工程师, IBM. 童 强国, 高级软件工程师, IBM. 简介: CSRF(Cross Site Request Forgery, 跨站域请求伪造)是一种网络的攻击方式,该攻击可以在受害者毫不知情的情况下以受害者名义伪造请求发送给受攻击站点,从而在并未授权的情况下执行在权限保护之下的操作,有很大的危害性.

再谈Spring MVC中对于CSRF攻击的防御

- - CSDN博客架构设计推荐文章
在Spring MVC应用中实施CSRF防御,一般会采用 EYAL LUPU的方案,该方案的基本思路是在生成表单时在其中插入一个随机数作为签名,在表单提交后对其中的签名进行验证,根据验证的结果区分该表单是否是经由应用签署的合法表单. 如果签名不正确或不存在签名,则说明请求可能已被劫持. EYAL LUPU方案的巧妙之处在于,通过使用HandlerInterceptorAdapter和Spring3.1中新引入的ReuqestDataValueProcessor这一对组合,使得签名和验证的过程无缝地集成到现有应用中.

网站攻防之CSRF和XSS跨站脚本攻击

- - CSDN博客推荐文章
进入正题之前,先扯一番:黑客本义并非某些人以为的利用网络干坏事的人,刚开始或者说现在的很多,黑客是以技术大牛的形式存在的,也就是在网络领域有一门专场的牛人. 有些黑客不干坏事而是干好事,比如利用网站的漏洞,去告诉网站开发运营者你的网站有漏洞,要修补啦,他们却并不会利用这漏洞干坏事,而是以发现漏洞追求技术快感为享受.

CSRF简介

- - 互联网 - ITeye博客
转自: http://www.cnblogs.com/hyddd/archive/2009/04/09/1432744.html.   CSRF(Cross-site request forgery),中文名称:跨站请求伪造,也被称为:one click attack/session riding,缩写为:CSRF/XSRF.

CSRF简单介绍及利用方法

- - lsh4ck
CSRF(Cross-site request forgery)跨站请求伪造,由于目标站无token/referer限制,导致攻击者可以用户的身份完成操作达到各种目的. 根据HTTP请求方式,CSRF利用方式可分为两种. 0x01 GET类型的CSRF. 这种类型的CSRF一般是由于程序员安全意识不强造成的.

防范 CSRF 跨站请求伪造

- - 文章 – 伯乐在线
CSRF(Cross-site request forgery,中文为 跨站请求伪造)是一种利用网站可信用户的权限去执行未授权的命令的一种恶意攻击. 通过 伪装可信用户的请求来利用信任该用户的网站,这种攻击方式虽然不是很流行,但是却难以防范,其危害也不比其他安全漏洞小. 本文将简要介绍CSRF产生的原因以及利用方式,然后对如何避免这种攻击方式提供一些可供参考的方案,希望广大程序猿们都能够对这种攻击方式有所了解,避免自己开发的应用被别人利用.

程序员必知(一):CSRF跨站请求伪造

- - CSDN博客研发管理推荐文章
首先说明一下什么是CSRF(Cross Site Request Forgery). 跨站请求伪造是指攻击者可以在第三方站点制造HTTP请求并以用户在目标站点的登录态发送到目标站点,而目标站点未校验请求来源使第三方成功伪造请求. JS控制浏览器发送请求的时候,浏览器是根据目标站点,而不是来源站点,来发送cookie的,如果当前会话中有目标站点的cookie,就发送出去.

D-link路由器CSRF漏洞利用详解

- - 牛X阿德马
本文的目的是展示CSRF漏洞的危害,以D-link的DIR-600路由器(硬件版本:BX,固件版本:2.16)的CSRF漏洞为例. D-link的CSRF漏洞已经是公开的,本文将详细描述一下整个D-link CSRF漏洞的利用,如何通过CSRF漏洞实现远程管理访问D-link路由器. 如果某些request请求中没有csrf  token或不需要密码授权,会存在CSRF漏洞,该漏洞允许攻击者伪造登录用户发送请求,因此可以导致用户执行攻击者想要的操作请求.

漏洞科普:对于XSS和CSRF你究竟了解多少

- - FreeBuf.COM
    随着Web2.0、社交网络、微博等等一系列新型的互联网产品的诞生,基于Web环境的互联网应用越来越广泛,企业信息化的过程中各种应用都架设在Web平台上,Web业务的迅速发展也引起黑客们的强烈关注,接踵而至的就是Web安全威胁的凸显.     黑客利用网站操作系统的漏洞和Web服务程序的SQL注入漏洞等得到Web服务器的控制权限,轻则篡改网页内容,重则窃取重要内部数据,更为严重的则是在网页中植入恶意代码,使得网站访问者受到侵害.