欢迎访问悦橙教程(wld5.com),关注java教程。悦橙教程  java问答|  每日更新
页面导航 : > > 文章正文

CSRF(跨站请求伪造),

来源: javaer 分享于  点击 5744 次 点评:89

CSRF(跨站请求伪造),


  在我刚上高中的时期,那时在线身份认证什么的还没现在这么完备,所以出门带好自己的身份证就成了重中之重。如果身份证丢了,回家肯定是避免不了坐下来喝着苦瓜茶,和老爸聊聊人生和理想了。之所以这么看重身份证这张小卡片,就是怕有别有用心之人,捡到身份证后到处贷款、借钱,倾家荡产不说,严重的话还可能莫名其妙被警察叔蜀黍赠送一副闪亮钛钢手铐和时尚黑白条纹套装。。。而在网络攻击中,有一种攻击就和盗用别人身份证很类似,未经你的允许,盗用你的信息去请求信任你的网站,使之完成自己的目的,它就是CSRF。

一、CSRF攻击定义:

  CSRF(Cross-site request forgery)跨站请求伪造,又叫”One Click Attack”或”Session Riding”,通常缩写为CSRF或XSRF。CSRF本质是一种对网站信任的恶意利用,简单的来说,就是用你的身份去请求信任你的网站,然后借此完成自己的目的。但是因为CSRF攻击比较的小众,所以用于防范这种攻击的手段并不多,正因为如此,CSRF才比较具有威胁性

二、CSRF攻击原理:


CSRF参考
从这样原理图我们可以看出来,完成一次CSRF攻击,至少需要两个步骤:
1.登录受信任的网站A,并在本地生成Cookie;
2.在不登出A的情况下,访问危险网站B;

需要注意的是,虽然这两个步骤缺一不可,但是我们很难保证自身没有以上的操作,如:
1.在登录了一个网站之后,不再打开一个tab页面并访问其他的网站;
2.不能保证在关闭了浏览器之后,本地的Cookie立即过期(浏览器关闭不等于回话结束)
3.攻击网站很可能是一个有漏洞但可信任且经常被访问的网站。

三、CSRF攻击防范:

1.验证HTTP Referer字段

  根据HTTP协议,在HTTP请求头中有个字段叫做Referer,它记录该HTTP请求的来源地址。通常情况,访问一个安全受限页面的请求来自于同网站。比如,需要访问一个http://bank.example/withdraw?account=bob&amount=1000000&for=Mallory网站,用户就必须需要先登录bank.example,然后通过点击页面上的转账按钮来触发转账事件。这个时候,转账请求的Refer值就会是转账按钮所在页面的URL,比如以“bank.example”域名开头的地址。而如果黑客想要对银行的网站发动CSRF攻击,就需要在他自己的网站构造请求,当这个请求发送到银行网站的时候,这个HTTP请求头的Referer指向的是黑客自己的网站。因此,想要防御CSRF攻击,则只需要对每个转账请求验证其Referer的值即可,若以“bank.example”域名开头的地址就是合法的,否则就是不合法的
  这种做法的好处就是简单易行,开发人员无需担心CSRF的漏洞,更不需要改动已有的代码,只需要对所有涉及安全敏感的请求统一加一个拦截器来检验请求的Referer即可。但是这种做法的不足之处就是Referer值是由浏览器生成的,虽然HTTP协议对此有明确的规定,但是每个浏览器的Referer实现方式可能是不相同的,而且并不能保证浏览器自身没有安全漏洞。****使用Referer验证的方法,就相当于把所有的安全性都依赖于第三方,从理论上来讲这是很不安全的。目前已经有一部分浏览器可以修改Referer的值了。

2.在请求地址中加入Token验证

  根据上面的描述,我们可以知道,CSRF之所以可以攻击成功,依靠的就是用户自身的Cookie,因为Cookie中保存了所有的用户验证信息,攻击者可以在不知道这些信息的情况下,直接利用用户的Cookie来通过安全验证。所以针对这个特点,我们可以很清晰的制定对策:即在请求中加入攻击者不能复制和伪造的信息,并且该信息不存在于Cookie之中,所以我们可以在HTTP请求中以参数形式加入一个随机产生的Token,并且在服务器端建立一个拦截器来验证这个Token,如果本次请求中没有包含TokenToken的内容不正确,则当做CSRF来拒绝本次请求
  这种做法相较于验证Referer来说要相对安全一些。我们可以在用户登录之后产生一个Token并且将其放入Session中,然后在每次请求的时候将TokenSession中取出,和请求中的Token进行验证,但是这种方式的难点在于如何将Token以参数的形式传入请求若是Get请求,则会变成http://url?csrftoken=tokenvalue的形式,若是Post请求,则要在<form>表单的最后加上<input type=”hiden” name=”csrfToken” value=”tokenValue”/>,但是这样对每一个请求都加上一个Token是非常麻烦的,并且容易遗漏,所以通常我们会将整个dom树都遍历,对其中所有的<a><form>都加上Token,这样可以解决大部分请求。但是对于页面加载之后动态生成的HTML代码,这种方法并不适用,需要我们手动添加Token
  除了上述的问题,Token本身的安全也是个问题。在一些可以发表自己内容的论坛等网站上,攻击者可以发表自己的网址,而系统也会在这些网址后面添加Token,攻击者由此可获得Token并发送攻击。为了避免这点,我们可以在系统中加入判断,若是链接指向的是内网系统,则添加Token,若是其他的私人网址,则不添加Token。可是即便如此,攻击者仍旧可以通过Referer来获取Token值并发送攻击。所以一部分用户喜欢手动关闭浏览器的Referer功能

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

  这种方法和使用Token验证类似,但是不同的是,并非是Token以参数的形式置于HTTP请求中,而是将其放入到HTTP投中自定义属性中通过XMLHttpRequest这个类,可以一次性给所有的该类请求加上csrfToken这个HTTP头属性,并将tokenValue放入其中。这样做的好处就是通过XMLHttpRequest请求的地址不会被记录到浏览器的地址栏,也不用担心Token会通过Referer泄露到其他网站

相关文章

    暂无相关文章
相关栏目:

用户点评