跨站请求伪造Cross-site request forgery(也称为CSRF、XSRF)是一种Web安全漏洞,允许攻击者诱导用户执行他们不打算执行的操作。攻击者通过伪造用户的浏览器的请求,向访问一个用户自己曾经认证访问过的网站发送出去,使目标网站接收并误以为是用户的真实操作而去执行命令。它允许攻击者部分规避同源策略,该策略旨在防止不同网站相互干扰。常用于盗取账号、转账、发送虚假消息等。攻击者利用网站对请求的验证漏洞而实现这样的攻击行为,网站能够确认请求来源于用户的浏览器,却不能验证请求是否源于用户的真实意愿下的操作行为。
CSRF与XSS不同,主要在于XSS是获取用户的凭证信息cookie、token、auth等,而CSRF是利用用户凭证信息,并不获取。由于CSRF漏洞的利用需要严格的条件限制,所以比较难利用,但是一旦被利用危害巨大。
1)浏览器会自动发送用户标识的会话信息,并且用户毫不知情也无法干预。
用户不知道浏览器发送的内容中已经包含身份标识信息。身份标识信息cookie、auth是站点用于识别受认证用户的一个标志。如果站点收到带有受害者认证信息的请求,那么这个请求就会被看作是已登录的受害者发送而来的正确操作请求。
2)攻击者了解在被攻击网站的特殊敏感操作的URL结构,并能分析其中所支持的参数和允许值。
一般而言,通过访问被攻击Web应用程序,查看潜入在HTML或JavaScript中的URL、分析提交的表单结构就可以了解到相应的信息。如果是一个开源项目,攻击者直接就可以从源代码中进行分析提取可以攻击的特殊敏感操作。
3)被攻击网站完全依赖于会话信息识别用户。
因为会话信息其实对浏览器而言是透明的,浏览器只负责存放在发送请求时附加相关的会话信息,通过浏览器并不能解析出会话信息的内容。为了提高Web应用的便利性,部分Web应用就会完全依赖这类信息来标识一个用户会话。从而导致Web应用程序不会判断一个请求是否真是由合法用户发送的。
一般来说,要发生跨站请求伪造攻击,需要有以下几个特点:
1)在受攻击站点已经登录,且没有正常退出。
2)受攻击站点的会话失效时间比较长,而且失效时间越长受攻击机率越高。
3)受攻击站点的特殊敏感操作没有严谨的用户身份标识验证。
4)受害者主动访问含有伪造请求的页面,如电子邮件、论坛、博客等常见的互联网应用都是攻击者可利用的社会工程学的范围。
1、用户User打开浏览器,访问受信任网站T,输入用户名和密码请求登录网站T;
2、在用户信息通过验证后,网站T产生Cookie信息并返回给浏览器,此时用户登录网站T成功,可以正常发送请求到网站T;
3、用户未退出网站T之前,在同一浏览器中,打开一个TAB页访问网站H;
4、网站H接收到用户请求后,返回一些攻击性代码,并发出一个请求要求访问第三方站点T;
5、浏览器在接收到这些攻击性代码后,根据网站H的请求,在用户不知情的情况下携带T网站的Cookie信息,向网站T发出请求。网站T并不知道该请求其实是由H发起的,所以会根据用户User的Cookie信息以User的权限处理该请求,导致来自网站H的恶意代码被执行。
GET类型的CSRF利用非常简单,只需要一个HTTP请求,这种类型的CSRF一般是由于程序员安全意识不强造成的,一般会这样利用:
在访问含有这个img的页面后,成功向http://test.com/csrf?xx=11
发出了一次HTTP请求。所以,如果将该网址替换为存在GET型CSRF的地址,就能完成攻击了。
这种类型的CSRF危害没有GET型的大,利用起来通常使用的是一个自动提交的表单,如:
访问该页面后,表单会自动提交,相当于模拟用户完成了一次POST操作,同样会提交到服务器,更改相关的信息。
空referer绕过,其他协议(data:)或https跳http
包含referer,但只检查是否包含网址,只需在我们的网站上创建一个文件/文件夹即可
仅验证了referer且未验证空referer情况(或无referer字段),利用data:协议绕过,如我们访问data:text/html,
则会显示referer为空
删除令牌:删除cookie参数中、url参数中的token,免服务器验证
令牌共享:创建两个帐户,替换token看是否可以互相共用
篡改令牌值:有时系统只会检查CSRF令牌的长度,而不校验令牌的数值
解码令牌值:尝试进行MD5或Base64解、编码
修改请求方法:post请求改为get请求
防御CSRF攻击的最可靠方法是在相关请求中包含CSRF令牌。令牌应该是:
1.对于一般的会话令牌,高熵确保是随机、不可预测的
2.session会话要绑定到用户
3.在执行相关操作之前都要经过严格的验证
GET接口太容易被拿来做CSRF攻击,接口最好限制为POST使用,GET则无效来降低攻击风险。
当然POST并不是万无一失,攻击者只要构造一个form就可以,但需要在第三方页面做,这样就增加暴露的可能性。
在通常情况下,验证码能很好遏制CSRF攻击。但是出于用户体验考虑,网站不能给所有的操作都加上验证码。
因此验证码只能作为一种辅助手段,不能作为主要解决方案。
开发使用token是一个验证机制,每个表单都存在一个字段token。如我们登陆了cookie后cookie会存在token,表单提交数据时会产生一个token,如果表单的token与cookie里的token相等时,则校验成功是本人,否则失败
验证http请求中的referer字段,通过验证访问前的url,Referer Check也可以被用于检查请求是否来自合法的“源”(Referer值是否是指定页面或者网站的域),如果都不是则极可能是CSRF攻击。
但是服务器并不是什么时候都能取到Referer,所以也无法作为CSRF防御的主要手段。但是使用Referer Check来监控CSRF攻击的发生,倒是一种可行的方法。
参考链接:
https://portswigger.net/web-security/csrf
https://mp.weixin.qq.com/s/H5FoF4Nwm2C-hZon2vrbUw
https://mp.weixin.qq.com/s/jiQupf9-I2t0fZgjqHagwg
https://mp.weixin.qq.com/s/MSK1f6qEAB75iiYzHWhlgA
https://cloud.tencent.com/developer/article/1516424
http://t.zoukankan.com/lan1x-p-8124814.html