CSRF漏洞探讨

混江龙づ霸主 提交于 2020-12-18 00:51:49

今天和大家聊聊CSRF(CrossSite Request Forgery)跨站点请求伪造


背景:节后上班的第一天,无心工作,还被告知今天的文章还没有发,心塞。又被告知负责的某个产品下某个页面存在一个跨站请求伪造漏洞,该漏洞会导致攻击者可以恶意通过浏览器盗用用户身份信息发送一些恶意请求,可能会存在盗号风险,心更塞。惨痛的教训总结最深刻的经验,这波经验无私奉献给你们。

 

一、CSRF原理

什么是CSRF?危害是什么?简单理解,CSRF是一种危险的恶意请求利用,攻击者利用用户本地的cookie,冒充用户发送一些恶意的请求,而这些请求对服务器来说是完全合法的。可能造成的后果是攻击者冒用用户名义发送消息、盗取账号、消耗账号内资源等。

用一个网上流传甚广的例子来说明

 

这就是CSRF攻击攻击原理及过程,为了大家更好理解,以上的过程简化为

浏览器在接收到这些攻击性代码后,根据网站B的请求,在用户不知情的情况下携带Cookie信息,向网站A发出请求。网站A并不知道该请求其实是由B发起的,所以会根据用户Cookie信息以用户的权限处理该请求,导致来自网站B的恶意代码被执行。

 

二、检测CSRF

       CSRF危害这么大,测试工程师在测试中怎么检测?

1.手动检测

用最通俗易懂的话告诉大家怎么操作:

步骤一:在搜狗浏览器(来一波广告)手动请求A接口fiddler抓取数据包,删掉Referer字段其他不变,重新提交请求(利用fiddlercomposer构造就行),如果请求通过,则大概率是存在CSRF漏洞。


步骤二:为了石锤这个漏洞,写一个HTML页面,这个页面主要工作就是发送该请求,修改用户信息(或者其他信息),就像这样


步骤三:在搜狗浏览器(你看我不是为了打广告,是为了告诉大家一定要在同一个浏览器进行操作)访问这个HTML页面,然后去查看用户信息是否被修改,如果修改成功,则石锤成功,报bug吧。

这个方法优点是简单粗暴实用,缺点是服务器请求比较多的时候会是一件繁重的工作。


2. CSRF漏洞检查工具

     CSRFTester,一款CSRF漏洞的测试工具。CSRFTester工具的测试原理大概是这样的,使用代理抓取我们在浏览器中访问过的所有的连接以及所有的表单等信息,通过在CSRFTester中修改相应的表单等信息,重新提交,相当于一次伪造客户端请求,如果修测试的请求成功被网站服务器接受,则说明存在CSRF漏洞。举一反三,此款工具可以检查CSRF漏洞反之也可以被用来进行CSRF攻击。大家不要学坏。


缺点:该工具仅支持简单的对页面所提交的表单信息进行抓取,然后由用户人工地进行修改该数据来确定是否存在csrf漏洞,效率低下,依然无法解决互联网海量漏洞检测的需求。

 

三、防御CSRF

针对CSRF的攻击原理,一般有以下三种常用的防御手段。

1.验证 HTTP Referer 字段

从原理图我们知道,攻击的来源是来自第三方网站,如果我们能判断当前HTTP请求的来源地址,并只允许来自本网站的的请求才能访问,那么CSRF攻击就失效了。根据 HTTP 协议,在 HTTP 头中有一个字段叫 Referer,它记录了该 HTTP 请求的来源地址,要防御 CSRF 攻击,wan.sogou.com网站只需要对于每一个请求验证其 Referer 值,如果是以wan.sogou.com 开头的域名,则说明该请求是来自搜狗游戏(再来一波广告)自己的请求,是合法的。如果 Referer 是其他网站的话,则有可能是黑客的 CSRF 攻击,拒绝该请求。


优点:简单易行,开发人员不需要操心 CSRF 的漏洞,只需要在最后给所有安全敏感的请求统一增加一个拦截器来检查 Referer 的值就可以,不需要改变当前系统的任何已有代码和逻辑,没有风险。


缺点Referer的值是由浏览器提供的,相当于安全性都依赖于第三方(即浏览器)来保障,实际上某些浏览器可以被篡改Referer的值。


2. token验证

CSRF攻击者之所以屡屡得手,是因为用户请求的验证信息都存在cookie中。攻击者甚至不需要知道验证信息具体是什么直接就通过cookie绕过了验证。针对这点,我们只要不将验证信息存放在cookie中即可。通常的做法是HTTP 请求中利用参数加入一个随机产生的 token,并在服务器端建立一个拦截器来验证这个 token,如果请求中没有token或者token内容不正确,则认为可能是CSRF攻击而拒绝该请求。


3.在HTTP头中自定义属性并验证

这种方法也是使用 token 并进行验证,和上一种方法不同的是,这里并不是把 token 以参数的形式置于 HTTP 请求之中,而是把它放到 HTTP 头中自定义的属性里。通过 XMLHttpRequest 这个类,可以一次性给所有该类请求加上 csrftoken 这个 HTTP 头属性,并把 token 值放入其中。这样解决了上种方法在请求中加入 token 的不便,同时,通过 XMLHttpRequest 请求的地址不会被记录到浏览器的地址栏,也不用担心 token 会透过 Referer 泄露到其他网站中去。


本文分享自微信公众号 - 搜狗测试(SogouQA)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!