赞
踩
检测CSRF攻击主要分两种:手工检测和半自动检测。并不是说没有全自动的CSRF检测工具,只不过这玩意误报率比较大,所以就不做介绍了。
在检测CSRF漏洞时,首先需要确定的一点是:CSRF只能通过用户的正规操作进行攻击,实际上就是劫持用户操作。所以,在检测前首先需要确定Web应用程序的所有功能,以及确定哪些操作是敏感的,比如修改密码、转账、发表留言等功能。
确定了敏感性操作后,使用这项“功能”并拦截HTTP请求,比如,如果删除用户操作URL为:
可以猜想,此时的参数项ID应该是用户的唯一标识信息,通过此ID可以删除指定的用户。在确定参数项的意义后,就可以验证该项功能是否存在CSRF漏洞。
编写CSRP POC为
打开这个HTML,JavaScript将自动提交这个form表单,当提交请求后,查看ID为5的用户是否被删除,如果被删除就可以确定存在CSRF漏洞。
在检测CSRF漏洞时,不像SQL注射、XSS漏洞那样,有时候必须要完全通过手动测试,而CSRF测试则不需要,CSRF漏洞最常用的是半自动检测。下面介绍常用的CSRF半自动检测工具:CSRFTester。这是一款OWASP组织提供的半自动CSRF漏洞测试工具,它可以拦截所有的请求,方便测试人员进行分析。
但我手里还没有这个软件,教程什么的估计有人系统地做过,就不在这多做笔记了。
之前给我们讲信息安全的老师,准备手敲简单的注入代码给我们做实验,找几个网站,点进去一看见验证码就跑了。可见验证码的实用程度(其实还是嫌麻烦)。
验证码。这可以说是对抗CSRF攻击最简洁有效的防御方法。CSRF攻击的过程,往往是在用户不知情的情况下构造了网络请求。而验证码强制用户必须与应用进行交互,才能完成最终请求。因此在通常情况下,验证码能够很好地遏制CSRF攻击。但验证码不是万能的,你不能总跟用户弹验证码,正常做的业务干啥都要验证码,用户也会烦的。因此验证码只能作为一种辅助手段,不能算是主要的解决方案。
再次询问。其实道理跟验证码有点像,就多弹一个框,问:你确定要这么做吗?如果用户是被攻击的,冷不丁弹这一个窗口,肯定会有所警觉,赶紧关掉了。可能正是这一环节阻止了攻击的进行。而且相较于验证码来说对用户体验损伤不大,但怕的是用户习惯性地直接点确定,毕竟面对两个选项与输入一串字符相比,前者思考的时间往往要短一些。
Referer Check在互联网中最常见的应用就是“防止图片盗链”。同理,Referer Check也可以被用于检查请求是否来自合法的“源”。Referer就是HTTP请求里面的内容,忘了再去复习一下。
常见的互联网应用,页面与页面之间都具有一定的逻辑关系,这就使得每个正常请求的Referer具有一定的规律。比如一个“论坛发帖”的操作,在正常情况下需要先登录到用户后台,或者访问有发帖功能的页面。在提交“发帖”的表单时,Referer的值必然是发帖表单所在的页面。如果 Referer的值不是这个页面,甚至不是发帖网站的域,则极有可能是CSRF攻击。
即使我们能够通过检查 Referer是否合法来判断用户是否被CSRF攻击,也仅仅是满足了防御的充分条件。Referer Check 的缺陷在于,服务器并非什么时候都能取到Referer。很多用户出于隐私保护的考虑,限制了Referer 的发送。在某些情况下,浏览器也不会发送Referer,比如从HTTPS跳转到HTTP,出于安全的考虑,浏览器也不会发送 Referer。
在flash的一些版本中,曾经可以自定义Referer头。虽然Flash在新版本中已经加强了安全限制,不再允许这么做,但是别的客户端插件允许了怎么办。这么看来,Referer Check也无法作为防御CSRF的主要手段,但用于监控CSRF攻击是肯定可行的。
CSRF为什么能攻击成功?本质原因就是重要操作的所有参数都是能被攻击者猜测到。攻击只有预测出URL的所有参数与参数值,才能成功地构造出一个伪造的请求;反之,攻击者将无法攻击成功。由于这个原因可以想出一个解决方案:把参数加密,或者使用一些随机数,从而让攻击者无法猜测到参数值。这时不可预测性原则的一种应用。不可预测性在《安全方案的设计原则笔记》里介绍过。
比如说一个删除操作的URL是:
把其中的username参数改成哈希值:
这样攻击者在不知道salt(什么是salt? 可见blog.csdn.net/acm_yuuji/article/details/27642221)的情况下,是无法构造出这个URL的,因此也就无从发起CSRF攻击了。而对于服务器来说,则可以从Session或Cookie中取得username=abc的值,再结合salt对整个请求进行验证,正常请求则会认为是合法的。
但是这个方法也存在一些问题。首先,加密或混淆后的URL将变得非常难读,对用户非常不友好。其次,如果加密的参数每次都改变,则某些URL 将无法再被用户收藏加书签。最后,普通的参数如果也被加密或哈希,将会给数据分析工作带来很大的困扰,因为数据分析工作常常需要用到参数的明文。
因此需要用一个更通用的法子,就是本节的题目 Anti CSRF Token。
Token即标志、记号的意思,在IT领域也叫令牌。
回到上面的URL中,保持原参数不变,新增一个参数Token。这个Token的值是随机的,不可预测:
要使Token足够随机,必须使用足够安全的随机数生成算法,或者采用真随机数生成器。Token应该作为一个“秘密”,为用户与服务器所共同持有,不能被第三者知晓。在实际应用时,Token可以放在用户的Session中,或者浏览器的Cookie中。由于Token的存在,攻击者无法再构造出一个完整的URL实施CSRF攻击。Token需要同时放在表单和Session中。在提交请求时,服务器只需验证表单中的Token,与用户Session(或Cookie))中的Token是否一致,如果一致,则认为是合法请求;如果不一致,或者有一个为空,则认为请求不合法,可能发生了CSRF攻击。
该Token根据“不可预测性原则”所设计,所以该Token的生成一定要足够随机,需要使用安全的随机数生成器生成Token。
此外,这个Token的目的不是为了防止重复提交。所以为了使用方便,可以允许在一个用户的有效生命周期内,在Token消耗前都使用同一个Token。但是如果用户已经提交了表单,则消耗这个Token,重新生成一个新的Token。
如果Token保存在Cookie 中,而不是服务器端的Session 中,则会带来一个新的问题。如果一个用户打开几个相同的页面同时操作,当某个页面消耗掉这个Token后,其他页面的表单内保存的还是被消耗掉的那个Token,因此其他页面的表单再次提交时,会出现Token错误。在这种情况下,可以考虑生成多个有效的Token,以解决多页面共存的场景。
最后还应注意Token的保密性。如果Token出现在了页面的URL中,则可能会通过Referer的方式泄露。比如如下URL
这个manage页面是一个用户面板,用户需要在这个页面提交表单或点击“删除”按钮才能完成操作。在这种场景下,如果这个页面包含了一张攻击者能指定地址的图片
那么上面那个URL会作为HTTP请求的Referer发送到img标签里提到的网址服务器上,导致Token泄露。因此在使用Token时,应该尽量把Token放在表单中。把敏感操作由GET改为POST,以form表单(或者AJAX)的形式提交,可以避免 Token泄露。
此外,还有一些其他的途径可能导致Token泄露。比如XSS漏洞或者一些跨域漏洞,都可能让攻击者窃取到Token的值。CSRF 的Token仅能用于对抗CSRF 攻击,当网站还同时存在XSS漏洞时,这个方案就会变得无效,因为XSS可以模拟客户端浏览器执行任意操作。在XSS攻击下,攻击者完全可以请求页面后,读出页面内容里的Token值,然后再构造出一个合法的请求。这个过程可以称之为XSRF,和 CSRF以示区分。
由XSS带来的问题,应该使用XSS 的防御方案予以解决,否则CSRF的 Token 防御就是空中楼阁。安全防御的体系是相辅相成、缺一不可的。
参考资料:《白帽子讲web安全》吴瀚清
《Web安全深度剖析》张炳帅
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。