阅读目录javascript
一:CSRF是什么?及它的做用?html
CSRF(Cross-site Request Forgery), 中文名字叫:跨站请求伪造。那么什么是跨站请求伪造呢?就是用户登陆一个正常的网站后,因为没有退出该正常网站,cookie信息还保留,而后用户去点击一个危险的网站页面,那么这个时候危险网站就能够拿到你以前登陆的cookie信息。而后使用cookie信息去作一些其余事情。java
所以须要完成一次CSRF攻击,须要完成以下事情:node
1. 登陆受信任的网站A,而且在本地生成cookie。
2. 在不登出网站A的状况下,继续访问危险网站B。git
所以CSRF基本原理是:假设A网站是一个银行网站,而我是该网站的用户,当我以受信任的身份登陆了该网站的时候,这时候A网站是经过cookie保留了咱们的登陆状态,这个时候我去登陆了恶意网站B的时候,B网站就会拿到我登陆A网站的cookie信息到,所以B网站就把拿到的cookie信息去从新请求A网站的接口,可是在该接口后面的参数作一些修改,所以就这样达到攻击的目的。github
二:CSRF 如何实现攻击web
demo(get请求)举例:安全
假如A网站,它转帐接口假如是get请求来完成转帐操做的话,好比我本地的demo查询接口就当作转帐接口来打比方吧。(http://localhost:6789/user/query2?name=&age=&sex=). 我这边的demo举例仍是以前的实现用户登陆查询数据那个demo来打比方哦(http://www.javashuo.com/article/p-rfgwwjrd-by.html).服务器
A网站查询接口是 http://localhost:6789/user/query2?name=&age=&sex= 这样的,而后当我查询(或叫转帐)完成后或登陆完成后,我该网站并无退出,而是继续作其余的事情,好比说切换到其余页面去,发现其余页面有个A片网站,我发现挺有兴趣的,
忽然点击进去,而后那个A片网站站点正好监听了银行转帐的接口,它把该接口方法一个A网站页面上去,而后以img标签的形式去请求下该接口。以下图所示微信
好比上面的 查看好看的妹子的代码以下:
<div> <a href="http://localhost:3001/" target="_blank">查看好看的妹子</a> </div>
它会连接到我B站点上的一个服务器下,该B站点的页面有以下代码:
<!DOCTYPE html> <html> <head> <meta charset=utf-8> <title>csrf攻击</title> </head> <body> <div> <img src="http://localhost:6789/user/query2?name=&age=&sex=" style="display:none" /> </div> </body> </html>
那么只要点击进来后,那么就会请求下这个查询接口(假如这个查询接口是转帐的接口的话),那么攻击者就会改下下get请求的参数,好比转帐给某某后,好比转帐10万给name=kongzhi, 那么kongzhi帐户上就新增了10万元了,可是登陆用户的帐户就减小了10万了。
出现如上缘由的是:使用get请求是不安全的操做,使用get请求去转帐,在访问网站B站点时候,因为咱们已经登陆了A银行网站,而在B站点中则是以 img标签的get方式去请求第三方资源(也就是A网站中的转帐接口)。所以B站点中的img中接口也会带上我网站A的cookie去请求数据,可是银行是根据cookie信息来进行判断的,只要cookie信息正确,银行就会把他们当作合法的请求,所以这样就会被攻击者利用了。
如上的demo,我使用node启动了2个服务,一个是 http://localhost:6789 服务,另一个是 http://localhost:3001/ 服务来进行演示下。
demo(post请求)举例:
因为get请求不安全,所以银行网站决定使用post来请求接口,好比我如今查询接口改为post了,以下所示:
可是B站点(攻击者的服务器)也与时俱进,也使用post请求接口,它使用的是隐藏iframe + form表单进行模拟post请求,好比B 站点的提交post请求的页面代码改为以下:
<!DOCTYPE html> <html> <head> <meta charset=utf-8> <meta name="referrer" content="never"> <title>csrf攻击</title> </head> <body> <div> <form method="post" action="http://localhost:6789/user/query" target="localwindow" id="formId"> <input type="hidden" name="name" value="11"/> <input type="hidden" name="age" value="30" /> <input type="hidden" name="sex" value="1" /> </form> <iframe style="display:none;" name="localwindow"></iframe> </div> <script type="text/javascript"> var f = document.getElementById('formId'); f.submit(); </script> </body> </html>
而后当咱们点击危险连接的时候,也会发出成功请求,转帐也能顺利进行。以下图所示:
如上演示也能够看到,攻击者也可使用csrf攻击成功。那么上面最主要的是演示 get/post 请求对于web安全性的内容,出现这样的状况,咱们该如何防范呢?
三:CSRF 防范措施
那么防范确定是在服务器端那边防范比较好,具体防范有以下几种:
1. 验证 HTTP Referer字段
HTTP协议中有一个访问来源的字段是Referer. 服务器端能够根据该字段进行判断,判断该来源的域名是不是本地网站,若是不是的话,能够直接认为是危险连接。拒绝访问。可是该方法仍是有缺陷的,好比我把我网站页面使用微信分享出去,而后其余人从微信朋友圈点击进来,那么该referer也不是本地域名网站的。
2. 加验证码
验证码虽然能够保证安全,可是验证码须要与用户交互,感受交互上比较麻烦点。可是因为用户体验的话,网站不可能给接口都加上验证码,可是能够对用户登陆加上的,好比咱们的博客园登陆的时候有时候须要验证码。验证码能够做为一种手段,可是不是最好的方法。
3. 使用Token
咱们常见的登陆页面,都是使用token来完成,能够确保安全性。想要了解 JSON Web Token, 能够看我以前一篇文章.
好比:用户登陆页面,登陆成功后,服务器端会生成一个token,放在用户的session或cookie当中,之后每次客户端与服务器端交互的时候都会把该token带过去,服务器端获取该token与本身服务器端保存的token对比,若是相同的话,说明是安全的,不然的话,会拒绝该请求的。