目录

Web安全之CSRF


1. CSRF介绍

来自维基百科

跨站请求伪造(英语:Cross-site request forgery),也被称为 one-click attack 或者 session riding,通常缩写为 CSRF 或者 XSRF, 是一种挟制用户在当前已登录的Web应用程序上执行非本意的操作的攻击方法。跟跨网站脚本(XSS)相比,XSS 利用的是用户对指定网站的信任,CSRF 利用的是网站对用户网页浏览器的信任。

跨站请求攻击,简单地说,是攻击者通过一些技术手段欺骗用户的浏览器去访问一个自己曾经认证过的网站并运行一些操作(如发邮件,发消息,甚至财产操作如转账和购买商品)。由于浏览器曾经认证过,所以被访问的网站会认为是真正的用户操作而去运行。这利用了web中用户身份验证的一个漏洞:简单的身份验证只能保证请求发自某个用户的浏览器,却不能保证请求本身是用户自愿发出的。

通俗的讲就是攻击者借用你的身份,执行某些你不想执行的非法操作。举个例子,某个网上银行转钱的请求是这样的:http://www.xxbank.com/pay.php?user=xx&money=100,其中user为收款方用户名,money为转账金额,当用户在该网站登陆后,发送这个请求就会给user转账money数额的钱。攻击者可以构造这样一个请求链接:http://www.xxbank.com/pay.php?user=attacker&money=100,然后诱导用户点击此链接,如果用户正在登陆状态中,就可以在用户未经允许的情况下将100元钱转给attacker用户。


2. 漏洞分类

  • GET型:例如http://www.xxx.com/user.php?newpasswd=123456,当访问此链接密码就会被修改成123456

  • POST型:例如如下请求,当提交此请求时就会被修改密码

    1
    2
    3
    4
    
    POST /user.php HTTP/1.1
    Host: www.xxx.com
      
    newpasswd=123456
    

3. 测试是否存在CSRF漏洞

  • 观察接口参数:参数是否固定、易猜测…
  • 测试请求流程:是否存在二次确认、验证码…
  • 删除Referer值,验证是否能请求成功
  • 是否存在token,如有token尝试将token参数删除或留空、能否获取或猜测到token

4. 利用方式

  • IMG标签:某些论坛发帖支持插入网络图片,可将GET型CSRF请求插入到其中,生成如这样的HTML代码<img src= "http://www.xxbank.com/pay.php?user=attacker&money=100",由于img标签的特点,当用户访问此帖子则会自动请求这个img标签中的链接,这样用户就会在无感知中受到CSRF攻击。利用本域的类似功能可绕过Referer验证防护机制

  • FORM表单:当CSRF为POST时,可利用FORM表单实现攻击。Burp中可生成PoC,请求包中右键 ==> Engagement tools ==> Generate CSRF PoC。下面是自动提交表单的PoC

    1
    2
    3
    4
    
    <form action="#" method="post" id="myform">
        <input type="hidden" name="pwd" value="123456" />
    </form>
    <script>document.getElementById('myform').submit()</script>
    
  • XSRF:XSS和CSRF可以结合起来使用,形成XSRF组合拳漏洞。例如一个网站同时有XSS漏洞和CSRF漏洞,那么就可以将CSRF链接插入到XSS漏洞的地方,这样就能神不知鬼不觉的执行CSRF攻击。并且这种组合方式,可以使Token防御方式失效,可以利用XSS获取Token,然后用JS发送CSRF请求

  • Referer绕过

    • 利用本域或子域链接:如果本域或子域有插入图片链接功能,即可利用此功能绕过Referer验证

    • 注册域名绕过:当Referer验证为http://xxx.com时,可以注册一个wwwxxx.com的域名,并将恶意链接部署在此域名上,即可绕过Referer验证

    • 文件名绕过:当Referer验证为http://xxx.com时,可在自己服务器上部署一个xxx.com.htmlHTML文件,访问此文件也可绕过Referer验证


5. 防御方案

  • 二次验证:进行敏感操作时,进行二次验证,例如再次输入密码、图片验证码等。这种方式是唯一能够彻底解决CSRF漏洞的方式,但这种方式会影响用户的体验。想象一下,你只是想修改一下性别都需要输入一次验证码,用户体验会变得极差

  • 验证Referer:服务端验证请求的Referer值,若为空或者其他域名,就拒绝该请求。这种方式可抵挡外域的CSRF攻击或者诱导点击,但如果本域存在插入图片链接等功能,那么将不能抵挡本域的CSRF攻击

  • Token认证:当用户登录后,随机一段字符串,存储在Session中,并响应在页面中,隐藏在FORM表单中,当进行敏感操作时,将此字符串以参数的形式通过请求一起发送到服务端,服务端一对比就能确定是否为正常请求。如果网站同时存在XSS和CSRF漏洞,那该防御方式将失效

  • 双重Cookie:在敏感操作时,将当前已登录的cookie隐藏在form表单中,提交敏感操作时,验证提交的参数是否有当前的cookie,没有或不一致就拒绝请求,这和token认证防御方案类似。同理,如果网站同时存在XSS和CSRF漏洞,可利用XSS获取cookie并当做参数传递,不过如果cookie开启了httponly,那么这种攻击方式可能会失效