CSRF那点事

本文详细介绍了CSRF(跨站请求伪造)的概念,包括其原理和危害,通过转账场景的示例解释了攻击过程。防御CSRF攻击的方法包括设置Cookie的SameSite属性和使用令牌机制。建议开发者采取客户端和服务端配合的解决方案,如服务端存储token或不存储token的策略,确保用户请求的安全性。
摘要由CSDN通过智能技术生成

CSRF那点事

概念

一般官话就是“跨站请求伪造”。但个人更习惯理解成“伪造跨站请求”。
简单来说,可以两方面来理解

  1. 跨站请求
    指的是恶意网站到有CSRF漏洞的网站的请求
  2. 伪造
    结合第一点,就是伪造一个恶意网站到有CSRF漏洞的网站的请求

那为什么会出现这个CSRF漏洞呢?

  1. 当浏览器请求服务器时,如果服务器将一些信息放入cookie,浏览器会将cookie临时保存起来,并在后续对颁发cookie的站点发起请求时,会自动将cookie一起提交给服务器。
  2. 传统的WEB应用会话的维持一般都是基于cookie-session的,即是说cookie中保存了用户的登录凭证。回过头看第一点,发现当浏览器发生同源请求时会一起将用户的登录凭证cookie一起发给服务器。那问题就来了,即使是不同的站点,只要发出cookie对应域的请求,都能自动上送cookie到服务器,从而达到伪造用户登录的请求,而此时服务器是无法区分的。

为了加深理解,举个栗子,最受关注的当属转账场景(太懒了,直接从Spring官方扒过来)
正常表单

<form method="post" action="/transfer">
	<input type="text" name="amount"/>
	<input type="text" name="routingNumber"/>
	<input type="text" name="account"/>
	<input type="submit"  value="Transfer"/>
</form>

提交转账申请时的HTTP请求

POST /transfer HTTP/1.1
Host: bank.example.com
Cookie: JSESSIONID=randomid
Content-Type: application/x-www-form-urlencoded

amount=100.00&routingNumber=1234&account=9876

恶意网站的表单

<form method="post"  action="https://bank.example.com/transfer">
	<input type="hidden"  name="amount" value="100.00"/>
	<input type="hidden" name="routingNumber"  value="evilsRoutingNumber"/>
	<input type="hidden" name="account" value="evilsAccountNumber"/>
	<input type="submit" value="Win Money!"/>
</form>

这个表单可以伪造成一些你感兴趣的东西,比如澳门风云什么的,只要你一点,即可触发上面提到的CSRF漏洞。那有的人说了,我不乱点不行吗,真不行,我想大多数人都遇到过,明明自己点的是一个正常的图片或者链接,却莫名其妙的被导向了一个其他站点,而提交表单的这个操作JavaScript可以自动完成,而加载JavaScript是浏览器自动的,所以,你可能会在无意间踩上雷。

如何防御

那作为开发者,我们应该如何防御CSRF攻击呢。我们既然知道了出现CSRF漏洞的原因(浏览器自动上送cookie),那就简单了。从大的方向而言一般分为两种解决方式

  1. 从源头解决
    既然这个问题是浏览器自动上送 cookie 造成的,那我们不让浏览器自动上送 cookie 不就行了,这就要用上 cookie 的一个属性 SameSite ,用上这个属性后,非同源的站点再伪造请求时,便不再上送cookie,但是这个属性存在一定的兼容性问题,具体支持列表参考这里,所以这个属性可以用,但最好不将其作为唯一防范手段
  2. 客户端配合服务端解决
    服务端和客户端配合又可以分为两种
    1. 服务端存储token
      用户登录后,给客户端返回cookie的同时,再额外返回一个token并将这个token存储在服务器当前用户的session下面;那么用户在下次请求时,需要将这个token一并提交给服务器,而服务器只需要校验这个token是否和当前用户session下的token是否匹配即可。
      注意这种方案的随机值,不能通过cookie传输,否则就失去了意义,可以同通过请求头或者表单隐藏域,其中这里面根据实际情况可以再调整,
      比如:这个token是用户登录到注销一直是一个呢,还是每次用了就换一个,这些根据实际场景,自行决定
    2. 服务端不存储token
      上面的方式需要服务端存储token,而这种方式,不需要存储,而是当服务端将token以cookie的形式返回给浏览器,客户端从cookie拿到这个token后,将它以请求头或者表单隐藏域的方式提交给服务端,而此时cookie中的token也会自动上传给服务端。服务端只需要判断cookie中的token与表单(或请求头)中的token是否匹配即可

完结

这里只是提供一个思路,不可直接用于生产环境。万能的网友可自行发散思维,定制出适合自己系统的防御工事。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值