CSRF详解

CSRF详解

简介

​ CSRF(Cross Site Request Forgery),也就是跨站域请求伪造,也可以缩写为XSRF,是一种对网站的恶意利用。虽然看起来跟XSS有点相像,但是两者基本是完全不同的。XSS利用的是站点内的信任用户,而CSRF则通过伪装成来自受信任用户的请求来利用受信任的网站。CSRF往往认为比XSS更具危险性和难以防范。

​ CSRF攻击能够盗用身份,以我们的名义发送恶意请求,发送邮件,发消息,盗取账号,购买商品,虚拟货币转账等。

CSRF攻击原理

​ 上图较为全面形象展示了CSRF攻击的整个过程。在上图中,A网站通过cookie来识别用户C,当用成功进行身份验证之后浏览器就会得到一个标识其身份的cookie,只要不关闭或者退出其登录,访问A网站都会带上这个cookie。如果在这个时候,用户C访问了被黑客控制的网站B网站B又发出要求访问网站A的请求,然后就会由用户C端根据网站B发起的请求,带着A网站的cookie访问网站A但这并不是用户C的本意,那么这就是所谓的请求伪造了,跨站是因为这是由B端发起的。而且这是受害者用户C完全不知情的请求,从而在未授权的情况下完成权限保护下的操作。

​ 举例子:

​ 比如说,受害者Bob在银行有一笔存款,通过对银行的网站发起请求http://bank.example/withdraw?account=bob&amount=1000000&for=bob2将1000000的存款转到bob2账户。通常情况下,该请求发送到网站后,服务器会先验证该请求是否来自一个合法的session,并且该session的用户Bob时已经成功登陆的,所以这个请求是会被响应的。

​ 恰巧在此时,黑客Mr.Hack知道了Bob身怀巨款,而自己在银行中也有一个账户hack,于是打起了坏心思,他知道上面那个url会进行转账操作。Mr.Hack可以自己发送一个请求,http://bank.example/withdraw?account=bob&amount=1000000&for=hack,但是虽然已经发送端银行服务器端了,但是服务器并不会响应,因为经过服务器验证,这个请求是没有合法cookie,服务器知道这并不是Bob用户发来的请求。

​ 这时,Mr.Hack灵机一动,想到了使用CSRF的攻击方式,他自己先做了一个网站,在网站中放入如下代码,这属于前端代码中标签的内容src="http://bank.example/withdraw?account=bob&amount=1000000&for=hack",然后Mr.Hack会使用浑身解数来引诱受害人Bob访问网站,比如广告或者一些颇具诱惑性的网页等。当受害人Bob访问该网站时,经过事件触发,受害者Bob自己的浏览器端就会发起上诉url中的请求,并且会附带Bob浏览器中的cookie。在大多数情况下,bank服务器端会拒绝该请求,因为服务器端并没有最近的cookie信息。但是Bob不巧在最近访问了该银行站点,他的浏览器中的cookie尚未过期,也就是与银行网站之间的seesion尚未过期的话,那就糟了。上面那个请求url就会得到相应,银行就真的将100000转到hack账户上了,而且受害人Bob目前还完全不知情。

注意事项

黑客能拿到cookie吗

​ 事实上,使用csrf攻击,黑客一般是不会拿到cookie的,也看不到cookie的内容。CSRF攻击是借助受害者的合法cookie骗取服务器的信任。

​ 黑客使用CSRF攻击实际主要是为了以受害者的身份执行所描述的命令,这一特点也正好是CSRF与XSS的区别所在,XSS是利用script文件相恶意服务器发送请求但这些请求是包含入侵方想要知晓的信息的,其主要目的是为了获取信息,窃取服务器中的数据,包括cookie。

什么样的请求是要CSRF保护的

​ 我们要保护的是那些可以直接改变数据的服务,而那些只能读取数据的服务则不需要CSRF的保护。通常而言,GET请求作为请求数据的请求而不会去修改数据,所以某些框架(如Spring Security)里防护CSRF的filter限定的method是POST/PUT/DELETE等,而没有限定GET。

​ 比如上面那个例子中转账的请求会直接改变账户的金额,一般为POST的请求,需要保护。而查询余额是对金额的读取操作,不改变数据,CSRF攻击就无法利用了。

CSRF防御的常规思路

验证HTTP Referer字段

​ 众所周知,在HTTP头中有个字段的名字叫Referer,它记录了该HTTP请求的来源地址。在通常情况下,访问一个安全受限页面的请求其referer需要来自同一个网站,比如需要访问http://bank.example/withdraw?account=bob&amount=1000000&for=hack,用户需要先登陆到bank.example,然后通过页面的转账按钮来触发转账事件。这时,该请求的referer值就是按钮所在的那个页面的url。但是如果黑客要实施CSRF攻击的话,referer的值就会是Mr.Hack自己所搭建的那个网站的url,而一经银行的服务器验证是站外请求,就会直接拒绝,从而防御CSRF攻击。

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

​ CSRF能够成功完全是因为黑客能够伪造用户的请求,在该请求中所有的用户验证信息都存在于cookie中,因此黑客才可以利用cookie来通过安全验证。要抵御CSRF,关键在于在请求中放入黑客不能伪造的信息,并且该信息不存在在cookie中。那么我们就可以在HTTP请求中以参数的形式加入一个随机生成的token,并在服务器端建立一个拦截器来验证这个token,如果请求中没有token或token的内容的不正确,则认为不安全从而直接拒绝该请求。(一般是服务器端生成的)

​ 具体内容可看下面这篇博客:CSRF攻击预防的Token生成以及验证原理 - 简书 (jianshu.com)

​ 使用token的一个难点就是如何把token以参数的形式加入请求。

在HTTP头中自定义属性并验证

​ 这里也是使用token并进行验证,和上一种方法不同的是,这里并不是把token以参数的形式置于HTTP请求中去,而是把它放到HTTP投中自定义的属性里。

参考文章

CSRF 详解:攻击,防御,Spring Security应用等 - pdai - 博客园 (cnblogs.com)

posted @ 2022-02-11 00:02  三木森林  阅读(2576)  评论(0编辑  收藏  举报