安全-CSRF学习分享

什么是 CSRF

CSRF(Cross-Site Request Forgery)的全称是“跨站请求伪造”,也被称为“One Click Attack”或者“Session Riding”,通常缩写为CSRF或者XSRF。

攻击者诱导受害者进入第三方网站,在第三方网站中,向被攻击网站发送跨站请求。利用受害者在被攻击网站已经获取的注册凭证,绕过后台的用户验证,达到冒充用户对被攻击的网站执行某项操作的目的。

CSRF攻击其实是利用了web中用户身份认证验证的一个漏洞:简单的身份验证仅仅能保证请求发自某个用户的浏览器,却不能保证请求本身是用户自愿发出的。

CSRF攻击的原理及流程

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1t0f9zkd-1645512286685)(https://bed.cdpt.pro/ibed/2021/11/10/DRztA12Qr.png)]

几种常见的CSRF攻击类型

1、GET类型

仅仅须要一个HTTP请求,就能够构造一次简单的CSRF:

<img src=http://www.mybank.com/transfer?toBankId=11&money=1000>

当访问带有此图片的页面时,浏览器会自动发出一次这样的HTTP请求:http://www.mybank.com/transfer?toBankId=11&money=1000

2、POST类型

这种类型的CSRF攻击通常是利用一个自动提交的表单:

<form action="http://www.mybank.com/transfer" method=POST>
    <input type="hidden" name="toBankId" value="11" />
    <input type="hidden" name="money" value="10000" />
</form>
<script> document.forms[0].submit(); </script> 

访问该页面时,表单会自动提交,相当于模拟用户完成了一次POST操作。

3、链接类型

这种类型的CSRF攻击不同于上面的两种,上面两种CSRF攻击只需要受害者进入页面就会触发,链接类型的CSRF攻击需要受害者点击链接才会触发:

<a href="http://www.mybank.com/transfer?toBankId=11&money=1000" taget="_blank">
	看片点我
<a/>

CSRF攻击的特点

CSRF通常是跨域的,因为外域通常更容易被攻击者掌控。但是如果本域下有容易被利用的功能,比如可以发图和链接的论坛和评论区,攻击可以直接在本域下进行。

攻击利用受害者在被攻击网站的登录凭证,冒充受害者提交操作,而不是直接窃取数据(整个过程攻击者并不能获取到受害者的登录凭证,仅仅是“冒用”)。

防御策略

针对CSRF攻击的特点,采取措施:

特点一: CSRF通常是跨域的

措施:同源检测

特点二: CSRF攻击者不能获取到Cookie等信息,只是“冒用”

措施:CSRF Token

同源监测

既然CSRF通常是跨域的,那么就直接禁止外域(或者不受信任的域名)对我们发起的请求。

HTTP协议中,每个异步请求的Header都会有一个Referer属性:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-L9UgCKDO-1645512286691)(https://bed.cdpt.pro/ibed/2021/11/09/DRdP4RwAb.png)]

Referer属性默认包含path和query:

Referer: http://www.mybank.com/transfer?toBankId=11&money=1000

Referer属性记录了该HTTP请求的来源地址。 对于Ajax请求,图片和script等资源请求,Referer为发起请求的页面地址。对于页面跳转,Referer为打开页面历史记录的前一个页面地址。因此我们可以使用Referer确定来源域名。

可以通过设置Referrer Policy来控制哪些访问来源信息可以在Referer中发送。(Referrer-Policy
这种方法并非万无一失,Referer的值是由浏览器提供的,虽然HTTP协议上有明确的要求,但是每个浏览器对于Referer的具体实现可能有差别,并不能保证浏览器自身没有安全漏洞。使用验证 Referer 值的方法,就是把安全性都依赖于第三方(即浏览器)来保障,从理论上来讲,这样并不是很安全。在部分情况下,攻击者可以隐藏,甚至修改自己请求的Referer(Referer隐藏和伪造)。

CSRF大多数情况下来自第三方域名,但并不能排除本域发起。如果攻击者有权限在本域发布评论(含链接、图片等),那么它可以直接在本域发起攻击,这种情况下同源策略无法达到防御的作用。

补充:

除了Referer属性,Header中还有一个属性Origin,记录HTTP请求的来源地址,Origin属性不包含path和query:Origin: http://www.mybank.com。但是Get和Head请求中没有Origin属性。

CSRF Token

CSRF攻击者不能获取到Cookie等信息,只是“冒用”。所以我们可以要求浏览器发送的请求中提供不保存在cookie中,并且攻击者无法伪造的数据作为校验,那么攻击者就无法再进行CSRF攻击了。

当用户登陆的时候,生成一个随机数,作为csrfToken存放在Cookie中:

HttpServletResponse.addCookie(new Cookie("csrfToken", UUIDHelper.getUuid()));

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gZpzRf0k-1645512286693)(https://bed.cdpt.pro/ibed/2021/11/09/DRedLyZQO.png)]

实现校验的两个实现方式:

一、当发送请求时,将Cookie中的csrfToken取出作为一个参数拼接在请求后面,后端接收到请求后,将Cookie中的csrfToken和请求中的参数做对比,如果相同则允许访问,反正则不允许。

二、当发送请求时,将Cookie中的csrfToken取出放到请求Head中,后端接收到请求后,将Cookie中的csrfToken和请求Head中的csrfToken做对比,如果相同则允许访问,反正则不允许。

为什么可以把csrfToken放在Cookie中?

CSRF攻击者不能获取到Cookie信息,只要系统没有XSS漏洞或者其他泄露Cookie的漏洞,那么CSRF攻击者就无法获取到Cookie中的csrfToken。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值