CSRF攻击方式及防御手段

admin 2023年9月21日11:20:07评论7 views字数 5087阅读16分57秒阅读模式
所谓的CSRF跨站请求伪造,与其说是“冒用”或“伪造”,不如说是一个“钓鱼陷阱”。因为前两个称呼夸大了CSRF的灵活性,实际上,它只是一段被恶意用户预设的,死的代码段,它是不具备主观能动性的,更像是一个陷阱,通过诱导不知真相的用户来触发,然后执行固定的脚本。”
CSRF简介

     CSRF定义

CSRF(Cross Site Request Forgery, 跨站/域请求伪造)是一种网络的攻击方式,CSRF通过伪装来自受信任的用户的请求来攻击受信任的网站。简单地说,是攻击者通过一些技术手段欺骗用户的浏览器去访问一个自己曾经认证过的网站并执行一些操作(如发邮件,发消息,甚至财产操作如转账和购买商品)。
CSRF攻击方式及防御手段
由于浏览器曾经认证过,所以被访问的网站会认为是真正的用户操作而去执行。这利用了web中用户身份验证的一个漏洞:简单的身份验证只能保证请求发自某个用户的浏览器,却不能保证请求本身是用户自愿发出的

     CSRF和XSS对比

跟跨网站脚本(XSS)相比,XSS 利用的是用户对指定网站的信任,CSRF利用的是网站对用户网页浏览器的信任。

CSRF原理
CSRF攻击的原理是这样的:
(1):当我们登陆某个网站以后,因为HTTP协议是无状态的,所以为了保存我们的登陆状态,服务器中的程序就必须创建一个session文件,用来保存我们的登陆信息。
(2):为了能够在多个页面相互切换访问之间,记录我们的状态,服务端首先会将一个响应的session文件对应的session_id传递给客户端浏览器。浏览器接收到以后就会将这个值写入到一个cookie文件中。在下一次访问该网站的内容的时候,就会将客户端本地所存储的属于该网站的cookie全部发送给服务端程序,其中就包括存储session_id的cookie。服务端如果需要检测请求者的身份,就可以根据传递过来的cookie中所包含的session_id来检测服务端是否存在响应的session文件以及session文件中的内容是否合法。如果检测合法,那么就验证用户身份合法,否则不合法。
(3):如果黑客在其他页面设置了一个链接,这个链接指向一个网站的转账系统。并且当前用户是这个网站的会员,并且处于登陆的状态(也就是客户端浏览器存在存储合法的session_id的cookie),那么当用户点击了这个链接以后,那么客户端浏览器就会将用户的这些信息进行传递到服务端,但是这个链接具体做了什么,用户根本不知道,这也就做到了伪造了用户的身份,做了用户都不知道的事情。。。
CSRF攻击的流程
CSRF攻击方式及防御手段

CSRF攻击原理过程如下:

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

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

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

CSRF攻击的对象
在讨论如何抵御 CSRF 之前,先要明确 CSRF 攻击的对象,也就是要保护的对象。从以上的例子可知,CSRF 攻击是黑客借助受害者的 cookie(session) 骗取服务器的信任,但是黑客并不能拿到 cookie,也看不到 cookie 的内容。另外,对于服务器返回的结果,由于浏览器同源策略的限制,黑客也无法进行解析。因此,黑客无法从返回的结果中得到任何东西,他所能做的就是给服务器发送请求,以执行请求中所描述的命令,在服务器端直接改变数据的值,而非窃取服务器中的数据。所以,我们要保护的对象是那些可以直接产生数据改变的服务,而对于读取数据的服务,则不需要进行 CSRF 的保护。比如银行系统中转账的请求会直接改变账户的金额,会遭到 CSRF 攻击,需要保护。而查询余额是对金额的读取操作,不会改变数据,CSRF 攻击无法解析服务器返回的结果,无需保护。
故:增删改需要防范CSRF攻击,而读无需防范

常见的CSRF攻击

     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中的一个合法的请求,但这里被不法分子利用了。所以你的浏览器会带上你的银行站点ACookie发出Get请求,去获取资源以GET的方式请求第三方资源(这里的第三方就是指银行站点了,原本这是http://www.mybank.com/Transfer.php?toBankId=11&money=1000,结果银行站点服务器收到请求后,觉得这是一个更新资源操作(转账操作),所以就立马进行转账操作。

     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

Refererhead的一部分,用于记录来源页,常用于防盗链,如果针对csrf的防御的话,Referer也是起到可以在某种程度上的作用,通过判断Referer是不是来源于自己网站的域名,来判断是不是csrf攻击。
即便如此,依然有不足之处,referer头是由浏览器提供的,就是服务器不是什么时候都能取到referer头,很多用户在出于隐私问题,都不会选择发送referer头,没有referer头发送至服务器,服务器可能就会判断这是csrf攻击,且如果一些浏览器对于Referer的值是可改写的,那么CSRF的攻击仍然有效。
验证Referer方式总计:
优点:使用方便,开发简单,一定程度上能预防CSRF攻击缺点:这种机制完全依托于浏览器,Referer字段容易被故意篡改,或者被禁用。

     Token验证

Token的出现弥补了这一个短板,首先token无需与用户进行交互,完全是浏览器和服务器的事儿,用户基本上无需做什么来操作token。其次就是token是服务器产生的随机数,当用户发来请求后,会返回一个token,并且在session中也会同时放置一个token,当用户再次需要操作请求时,会带上token,收到请求后,服务器会将tokensession取出和请求带上的token进行对比,如果一致,则操作合法,反之,不合法!也因此,token在不影响用户的使用上,还可以有效阻挡csrf的攻击,一举两得!!!
添加token方式总结:
安全程度比Referer更高实现方式上稍微复杂需要保证token存储的安全

     双重Cookie验证

“csrfToken校验流程,实际上叫做《双重Cookie验证》,本质上是客户端发了两个token给服务端,一个在请求中,一个在cookie中,需要服务端解密后比对二者,检查是否合法和是否被篡改。详细过程如下:
在用户登录后,由客户端生成一个令牌token(加密,且伪随机),将其放入cookie中在请求时,携带Cookie一起发送,并将token作为参数拼接在url后后端校验发送过来的Cookie中的token和url后的参数是否相等要求每个请求都将此token作为隐藏表单值

     令牌同步模式

另一种类似的防止CSRF的方法是《令牌同步模式》本质上还是在服务端存了token,然后拿它和客户端发来的请求中带的token比对。
这是目前主流的 CSRF 攻击防御方案。具体的操作方式就是在每一个 HTTP 请求中,除了默认自动携带的Cookie 参数之外,再提供一个安全的、随机生成的宇符串,我们称之为 CSRF 令牌。这个 CSRF 令牌由服务端生成,生成后在 HtpSession 中保存一份。当前端请求到达后,将请求携带的 CSRF 令牌信息和服务端中保存的令牌进行对比,如果两者不相等,则拒绝掉该HITTP请求。详细过程如下:

1、由服务端生成一个伪随机、且加密的token(令牌),可以针对每个用户会话或针对每个请求生成一次,然后发送给客户端。

2、当客户端发出请求时,携带该令牌用以服务器端校验,只有和服务端存储在session中的令牌一致,才正常响应,否则拒绝这次请求。

3、CSRF令牌不应使用Cookie进行传输(防范xss攻击),而是--

   3.1、在隐藏字段form参数中添加令牌,或者

    3.2、在自定义HTTP请求标头中插入CSRF

再者,CookiehttpOnly属性,阻止客户端读取cookie,仅允许cookie被用在请求中,它是通过kill掉浏览器的document.cookie 属性,只有在http请求头中会带有此cookie的信息,以此阻止xss攻击窃取cookie的。
然后,CookiesameSite属性,阻止跨站请求携带cookie,它是通过指定一个Cookie 是否能被跨站发送来限制第三方Cookie的,说白了就是阻止B网站触发csrf脚本请求A网站接口时,不让该请求携带Cookie
最后,Cookiedomain属性,是阻止跨站读取cookie的作用。

     疑问

既然冒用者可以冒用合法用户的cookie,用户的COOKIE就像是一张门禁卡一样,攻击者可以盗用用户的门禁卡,以被盗用户的身份来执行一些设计增删改的操作,既然用户已经盗用了用户的COOKIE刷卡进门了,这个COOKIE对攻击者的防御也应该也就失效了才对呀?
根据上述csrf Token校验流程,说到客户端浏览器会在请求网站A的服务端的时候,在Cookie中带一个token(token是随机数,且每次操作完都会重新生成),还会在请求头/体或者请求参数中带一个token,然后由服务端对比二者是否一致。这是正常的校验流程。那么第一个关键点就来了:在非正常的,csrf攻击过程中,陷阱那段脚本(请求)是不变的,且是预设的,因此无法预知是哪个用户踩中了陷阱,就无法在这个请求体中加上该用户的token!因此必不可能通过网站A后端的校验比对。
虽然无法预设这个陷阱触发的请求的token,但可以在脚本中即时获取踩中这个陷阱的当前用户的cookie中的token呀?比如我们自己开发时就能够通过getCookie获取到其中内容...
那么,第二个关键点来了:浏览器的CORS同源策略!!现在我点击触发了这个陷阱,浏览器引擎执行B网站当前页面的这个陷阱脚本时,假设其中有getCookie()类似代码,想要拿到的资源(就是我本地存储cookie的那个文件),但这时候它是在B网站触发的,由于当前页面的域名ip与我的主机ip不一致导致跨域了,因此浏览器会阻止B网站共享到该资源(我本地的cookie文件)

原文始发于微信公众号(安全防护):CSRF攻击方式及防御手段

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2023年9月21日11:20:07
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   CSRF攻击方式及防御手段http://cn-sec.com/archives/2055167.html

发表评论

匿名网友 填写信息