什么是CSRF攻击,如何防范CSRF攻击?

x33g5p2x  于2022-03-03 转载在 其他  
字(3.1k)|赞(0)|评价(0)|浏览(291)

一、什么是CSRF攻击
CSRF攻击的全称为跨站脚本伪造,也称为One Click Attack或者Session Eiding,通常缩写为CSRF或者XSRFCSRF通过伪装来自受信任的用户的请求来攻击受信任的网站。与XSS相比,CSRF攻击往往不太流行(因此对其进行防范的资源也是相当紧缺的)和难以防范的,所以被认为比XSS更具危险性。我们可以这么理解CSRF攻击:首先攻击者会先盗用你的身份,然后以你的名义进行某些非法操作,甚至盗走你的账户购买的商品等。CSRF攻击其值是利用web中用户身份认证验证的一个漏洞:简答的身份验证仅仅可以保证请求发自某一个用户的浏览器,却无法保证请求本身是用户资源发出的。
二、CSRF攻击的流程

CSRF攻击原理过程如下:

1、用户C打开浏览器,访问安全网站A,输入用户名和密码请求登录网站A.
2、在用户信息通过验证后,网站A产生Cookie信息并返回给浏览器,此时用户登录A成功,可以正常发送请求到网站A。
3、用户没有退出A之前,在同一个浏览器中,打开一个Tab页面来访问网站B.
4、网站B接收到用户的请求后,返回一些攻击代码,并且发出一个请求要求访问第三方站点A.
5、浏览器在接收到这些攻击性代码后,根据网站B的请求,在用户不知情的情况下携带Cookie信息,向网站A发出请求。网站A并不知道该请求其实是由B发出的,所以会根据用户C的cookie信息以C的权限处理该请求,导致来自网站B的恶意代码被执行。

从上述的流程可以看出,想要达成CSRF攻击,必须达成两个基本条件。

1、登录受信任网站A,并且在本地生成Cookie。
2、在不退出登录网站A的前提下,访问危险网站B.

三、常见的CSRF攻击
1、GET类型的CSRF

银行站点A: 它以GET请求的方式来完毕银行转账的工作:如http://www.mybank.com.Transfer.php?toBankId=11&money=1000
危险站点B:其中存在一段html代码为<img src=http://www.mybank.com/Transfer.php?toBankId=11&1000>
首先你登录了银行站点A,然后访问危险站点B,这时你就会发现自己的银行账号少了1000元。为什么会这样呢?原因是银行站点A违反了HTTP规范,使用GET请求更新资源。在訪问危急站点B的之前,你已经登录了银行站点A,而B中的 一个合法的请求,但这里被不法分子利用了)。所以你的浏览器会带上你的银行站点A的Cookie发出Get请求,去获取资源以GET的方式请求第三方资源(这里的第三方就是指银行站点了,原本这是http://www.mybank.com/Transfer.php?toBankId=11&money=1000 ,结果银行站点服务器收到请求后,觉得这是一个更新资源操作(转账操作),所以就立马进行转账操作。

2、POST类型的CSRF

这种类型的CSRF危害没有GET类型的大,利用起来通常使用的是一个自动提交的表单,如
<form action=http://wooyun.org/csrf.php method=POST>
    <input type="text" name="xx" value="11" />
</form>
<script> document.forms[0].submit(); </script> 
访问该页面后,表单会自动提交,相当于模拟用户完成一次POSt操作。

四、CSRF测试
检测CSRF漏洞是一项比较繁琐的工作,最简单的方法就是抓一个正常请求的数据包,去掉Referer字段后再重新提交,如果该提交还有效,那么基本可以确定存在CSRF漏洞。随着对CSRF漏洞研究的不断深入,不断涌现一些专门针对CSRF漏洞进行检测的工具,比如CSRFTester,CSRF Request Builder等,以CSRF Tester工具为例,CSRF漏洞检测工具的测试原理如下:使用CSRFTester进行测试时,首先需要抓取我们在浏览器中访问过的所有链接以及所有的表单等信息,然后通过在CSRFTester中修改相应的表单等信息(比如说更改Referer字段的信息),重新提交,这相当于一次伪造客户端请求。如果修改后的测试请求成功被网站服务器接受,则说明存在CSRF漏洞,当然此款工具也可以被用来进行CSRF攻击。
五、预防CSRF攻击
5.1、验证HTTP Referer字段
还拿上述的银行转账的例子来说,首先我们向银行站点发出一个请求时,此时HTTP协议头部会携带Referer字段,其中包含着请求该站点的域名,此时如果我们在访问银行站点时并且向银行发出请求,此时携带的Referer就是mybank.com,如果此时我们从存在危险的网站B向银行站点发起请求,此时的Referer就是危险网站B的域名。所以我们可以通过判断Referer来进行判断是否可以执行操作。这样就会很简单的就防止了CSRF,但是任然存在一些问题,比如说我们通过检查Referer来判断域名,这种决策权在浏览器,此时如果一些浏览器对于Referer的值是可改写的,那么CSRF的攻击任然有效。还存在一些用户会禁用Referer字段,此时就会造成无法请求网站数据。
验证Referer方式总计:
优点:使用方便,开发简单,一定程度上能预防CSRF攻击
缺点:这种机制完全依托于浏览器,Referer字段容易被故意篡改,或者被禁用。
5.2、添加token验证
我们可以当用户请求时,在安全站点A中生成一个SessionId,保存在服务器端,该值可以作为token传递给客户端。客户端可以设置一个隐藏的input框,其中的值为该token,当我们进行请求时,就会将该值传入到站点A的服务器,此时在服务器端就可以进行比较生成的token和保存的token是否一样,如果一样的话,就表示是从安全站点上发出的请求,就做出具体的相应。在危险网站B就无法拿到token,所以也就无法进行正确的请求了。如果使用的是post请求,我们可以放入隐藏的input框中,如果要是get请求,则我们可以如下写法。例如https://www.myBank.com?token=XXXXX。那么一个网站中存在很多请求,此时我们如果每一个都设置token,则就会显得非常的笨拙。此时我们可以遍历全部的dom,获取全部的a标签和form标签,进行添加就行了。但是如果页面的DOM是动态生成的,则需要程序员自己编写代码将token放入。还存在一个问题就是:如何才能保证token不被攻击者截获。
添加token方式总结:
安全程度比Referer更高
实现方式上稍微复杂
需要保证token存储的安全性
5.3、在HTTP头中自定义属性并验证
这种方法也是保存token,但是其实和上述不同的是,其在HTTP头部保存token,我们可以一次性给访问该网站的请求都加上该自定义字段,但是如何将数据存放在HTTP中呢?此时我们就需要另一个模块,XHRHTTPRequest,当我们使用该模块时,存在另一个弊端,就是只能是异步请求。其他请求都是无法访问的。另外,对于没有进行 CSRF防护的遗留系统来说,要采用这种方法来进行防护,要把所有请求都改为 XMLHttpRequest 请求,这样几乎是要重写整个网站,这代价无疑是不能接受的。
验证head方式总结:
1、使用方式简单,不容易泄漏
2、使用地方局限

相关文章