关于CSRF攻击的原理以及防御措施

另一种常见的攻击XSS,看这篇文章。XSS攻击原理和防御措施
跨站点请求伪造攻击:是一种挟制用户在当前已登录的Web应用程序上执行非本意的操作的攻击方法,CSRS 利用的是网站对用户网页浏览器的信任。

CSRS攻击的原理

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

实例:受害者Bob在银行里有一笔存款,通过对银行的网站发送请求http://bank.example/withdraw?account=bob&amount=1000000&for=bob2可以向bob2转账1000000。通常情况下,该请求发送到网站后,服务器会先验证该请求是否来自一个合法的session,并且该session用户Bob已经成功登陆。
黑客abc在该银行里也有账户,他知道上述的转账的URL,所以abc就可以发送一个请求给银行:http://bank.example/withdraw?account=Bob&amount=1000000&for=abc,但是该请求是来自abc而非Bob,所以他不能通过安全验证,因此该请求不会起作用。
此时,abc想到CSRS攻击方式,他先自己做一个网站,放入代码http://bank.example/withdraw?account=bob&amount=1000000&for=bob2,并且通过广告等诱使B来访问他的网站。当Bob访问该网站时,上面的URL就会发向银行,而且这个请求会附带Bob浏览器的cookie一起发向银行。大多数情况下会失败,因为他要求Bob认证信息,但是如果Bob当时恰巧访问银行服务器不久后,此时的session还没有过期,cookie中含有Bob的认证信息。此时,银行就会执行恶意代码,上述的URL就会得到响应,钱从Bob的账号中转移到了abc的账户,此时Bob毫不知情。等以后Bob再去查日志,也会显示来自于他本人的合法请求转移了资金,没有被任何攻击的痕迹。

CSRS的预防措施
  • 使用http的referer字段
    关于referer的作用戳这里
    比如要想访问http://bank.example/withdraw?account=bob&amount=1000000&for=bob就必须先登录http://bank.example,然后通过点击页面上的按钮来转发事件。此时动账请求就会指向以bank.example域名开发的地址,如果黑客使用的是CSRS攻击,他只能在自己网站来实施CSRS攻击,那么他发出的请求中referer就会指向黑客自己的网站,那么服务器就会拒绝访问。服务器只需要在每个动账请求中验证referer,如果指向的是以bank.example域名开发的地址,那么就代表是合法请求,反之,就可能是黑客的CSRS攻击,服务器拒绝该请求。

    优点:该方法简单易行,网站的普通开发人员不需要担心CSRS攻击,只需要在最后给所有安全敏感的请求都加一个referer拦截器,不需要改变当前系统的任何代码和逻辑,没有风险,非常便捷。
    缺点:该方法也不是万无一失的,因为有些浏览器是可以篡改refere的值,比如IE5和FF12。


  • 在请求地址中添加token并验证

CSRS之所以能够跨站点请求伪造攻击,是因为黑客可以完全伪造用户的请求,该请求中的用户验证信息全部都是存于cookie中,因此黑客可以在不知道这些验证信息的情况下直接利用用户的cookie来通过安全验证。要想抵御黑客的攻击,就要将请求放于黑客不能构造的信息中,并且该信息不存于cookie中,可以在http请求中以参数的形式加入一个随机产生的token中,并在服务器中建立一个拦截器来验证该token,如果请求中没有token或者token的内容不正确,那么就拒绝访问。

token可以在用户登录之后放于session中,然后每次请求都从session中拿出,与请求中的token相比。
如果是GET请求:token会附在地址的后面。
如果是POST请求:在from 的后面加上

优点:会比refere安全
缺点:在一个网站中,请求的地方有很多,对于每一个请求都要加上token是非常麻烦的,一般会在每次页面加载的时候,使用javascript遍历整个dom树,动态生成的dom需要手动添加。还有就是难以保证token本身的安全。


  • 在http头字段自定义属性添加token属性并验证
    将token放于http头中的自定义属性里。

优点:可以一次性给所有类请求都加上http的头属性,并且通过XMLHttpRequest不会被记录到浏览器的地址栏,也不用担心referer被泄露出去。
缺点:Ajax局部刷新,并非所有的请求都适合用这个类来发起,而且通过该类请求得到的页面不能被浏览器所记录下,从而前进后退刷新收藏等操作,给用户带来不便。

本文借鉴stpeace的文章

你可能感兴趣的:(前端小知识,CSRF,网站安全,跨站点请求伪造攻击)