CSRF攻击原理和防护措施讲解

CSRF攻击利用用户已登录的身份,通过伪装的请求修改用户信息。防护措施包括Token验证,同源检测和使用SamesiteCookie属性防止第三方请求携带Cookie。Samesite属性的Strict和Lax模式各有优缺点,目前在浏览器兼容性和子域支持上仍有局限。
摘要由CSDN通过智能技术生成

CSRF攻击原理讲解

CSRF(Cross Site Request Forger)跨站请求伪造

CSRF是如何攻击的

这样的,比如你在 http://wwww.aaa.com 网站里面, 你现在登录了

假如,有一个修改密码的接口,需要传一个用户名和新密码就能修改,并且要向后端传cookiecookie校验通过了就进行修改

get请求

http://wwww.aaa.com?username=zhangsan&newPassword=123456我们这样调用接口就能修改成功 黑客网站 http://wwww.bbb.com

<a href="http://wwww.aaa.com?username=zhangsan&newPassword=123456" target="_blank">点击看美女
</a> 

你就看见美女兴奋去点击了,因为刚才我们说了你是登录着的,新标签打开了aaa网站,就会去请求 http://wwww.aaa.com?username=zhangsan&newPassword=123456这个接口,因为现在本来就在aaa网站下的,就不会存在跨越问题,所以就会默认携带cookie去请求。这样就把你的信息给修改了, 这样黑客不知道你的密码,但修改成了新的密码,他就能用这个新的密码去登录你的aaa网站了,你的信息就都被盗取了

post请求

我们新打开一个窗口,在地址栏中输入链接,回车,这就是一个get请求 但如果我们修改密码是post提交呢?那黑客怎么做,那就需要用表单了,这样就可以发送的是post请求,点击的时候也会跳转到aaa网站,也就会携带cookie

<form action="http://wwww.aaa.com" method="post"><<img src="https://ask.csdn.net/channel/11" method="post"> --><input type="text" name="username" value="zhangsan" hidden><input type="text" name="newPassword" value="123456" hidden><button type="submit">点击查看美女</button" style="margin: auto" />
</form> 

我们写一个例子,从我们本地就看见跳转成功了,发送了请求,把cookie携带上了

是从我们本地 http://127.0.1:5500跳过去的,可以看见origin

防护措施

1、Token验证

既然浏览器默认会携带cookie, 那我们就使用token来验证,放在请求头里,这样浏览器就不会自动携带了

2、同源检测

既然CSRF大多来自第三方网站,那么我们就直接禁止外域(或者不受信任的域名)对我们发起请求

  • Origin Header
  • Referer Header

这两个Header在浏览器发起请求时,大多数情况会自动带上,并且不能由前端自定义内容。 服务器可以通过解析这两个Header中的域名,确定请求的来源域。

###3、Samesite Cookie属性

Chrome 51开始,浏览器的Cookie新增加了一个SameSite属性,用来防止CSRF攻击和用户追踪。Samesite有三个可选值,分别为Strict、Lax、None。

Samesite Cookie属性

防止CSRF攻击的办法已经有上面的预防措施。为了从源头上解决这个问题,Google起草了一份草案来改进HTTP协议,那就是为Set-Cookie响应头新增Samesite属性,它用来标明这个 Cookie是个“同站 Cookie”,同站Cookie只能作为第一方Cookie,不能作为第三方Cookie,Samesite 有两个属性值,分别是 Strict 和 Lax,下面分别讲解:

Samesite=Strict

这种称为严格模式,表明这个 Cookie 在任何情况下都不可能作为第三方 Cookie,绝无例外。比如说 b.com 设置了如下 Cookie:

Set-Cookie: foo=1; Samesite=Strict
Set-Cookie: bar=2; Samesite=Lax
Set-Cookie: baz=3 

我们在 a.com 下发起对 b.com 的任意请求,foo 这个 Cookie 都不会被包含在 Cookie 请求头中,但 bar 会。举个实际的例子就是,假如淘宝网站用来识别用户登录与否的 Cookie 被设置成了 Samesite=Strict,那么用户从百度搜索页面甚至天猫页面的链接点击进入淘宝后,淘宝都不会是登录状态,因为淘宝的服务器不会接受到那个 Cookie,其它网站发起的对淘宝的任意请求都不会带上那个 Cookie。

Samesite=Lax

这种称为宽松模式,比 Strict 放宽了点限制:假如这个请求是这种请求(改变了当前页面或者打开了新页面)且同时是个GET请求,则这个Cookie可以作为第三方Cookie。比如说 b.com设置了如下Cookie:

Set-Cookie: foo=1; Samesite=Strict
Set-Cookie: bar=2; Samesite=Lax
Set-Cookie: baz=3 

当用户从 a.com 点击链接进入 b.com 时,foo 这个 Cookie 不会被包含在 Cookie 请求头中,但 bar 和 baz 会,也就是说用户在不同网站之间通过链接跳转是不受影响了。但假如这个请求是从 a.com 发起的对 b.com 的异步请求,或者页面跳转是通过表单的 post 提交触发的,则bar也不会发送。

生成Token放到Cookie中并且设置Cookie的Samesite,Java代码如下:

 private void addTokenCookieAndHeader(HttpServletRequest httpRequest, HttpServletResponse httpResponse) {//生成tokenString sToken = this.generateToken();//手动添加Cookie实现支持“Samesite=strict”//Cookie添加双重验证String CookieSpec = String.format("%s=%s; Path=%s; HttpOnly; Samesite=Strict", this.determineCookieName(httpRequest), sToken, httpRequest.getRequestURI());httpResponse.addHeader("Set-Cookie", CookieSpec);httpResponse.setHeader(CSRF_TOKEN_NAME, token);} 

代码源自OWASP Cross-Site_Request_Forgery #Implementation example

我们应该如何使用SamesiteCookie

如果SamesiteCookie被设置为Strict,浏览器在任何跨域请求中都不会携带Cookie,新标签重新打开也不携带,所以说CSRF攻击基本没有机会。

但是跳转子域名或者是新标签重新打开刚登陆的网站,之前的Cookie都不会存在。尤其是有登录的网站,那么我们新打开一个标签进入,或者跳转到子域名的网站,都需要重新登录。对于用户来讲,可能体验不会很好。

如果SamesiteCookie被设置为Lax,那么其他网站通过页面跳转过来的时候可以使用Cookie,可以保障外域连接打开页面时用户的登录状态。但相应的,其安全性也比较低。

另外一个问题是Samesite的兼容性不是很好,现阶段除了从新版Chrome和Firefox支持以外,Safari以及iOS Safari都还不支持,现阶段看来暂时还不能普及。

而且,SamesiteCookie目前有一个致命的缺陷:不支持子域。例如,种在topic.a.com下的Cookie,并不能使用a.com下种植的SamesiteCookie。这就导致了当我们网站有多个子域名时,不能使用SamesiteCookie在主域名存储用户登录信息。每个子域名都需要用户重新登录一次。

总之,SamesiteCookie是一个可能替代同源验证的方案,但目前还并不成熟,其应用场景有待观望。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值