【Spring Security系列】跨域请求伪造的防护

本文详细介绍了CSRF(跨站请求伪造)攻击的概念、攻击过程及其对系统安全的危害。针对CSRF的防御手段,重点讲解了HTTP Referer检测和CsrfToken认证方法,并探讨了它们的优缺点。此外,文章深入剖析了Spring Security如何防御CSRF攻击,包括CsrfFilter的工作原理以及默认的HttpSessionCsrfTokenRepository和CookieCsrfTokenRepository的使用。最后,提到了Spring Security 4.1.0引入的LazyCsrfTokenRepository,以优化CSRF防护的资源利用率。
摘要由CSDN通过智能技术生成

CSRF的全称是(Cross Site Request Forgery),可译为跨域请求伪造,是一种利用用户带登录 态的cookie迚行安全操作的攻击方式。CSRF实际上并不难防,但常常被系统开发者忽略,从而埋下巨 大的安全隐患。

1.CSRF的攻击过程

为了试图说明CSRF的攻击过程,现在思考下面这个场景。

假如有一个博客网站,为了激励用户写出高质量的博文,设定了一个文章被点赞就能奖励现金的 机制,于是有了一个可用于点赞的API,只需传入文章id即可:

http://com.example.com/article/like?id=xxx

在安全策略上,限定必须是本站有效登录用户才可以点赞,且每个用户对每篇文章仅可点赞一 次,防止无限刷赞的情况发生。

这套机制推行起来似乎没什么问题,直我们发现有个用户的文章总是有非常多的点赞数,哪怕只是发表了一条个人状态也有非常多的点赞数,而这些点赞记录也确实都是本站的真实用户发起的。察觉到异常之后,开始对这个用户的所有行为进行排查,发现该用户几乎每篇文章都带有一张很特别的 图片,这些图片的URL无一例外地指向了对应文章的点赞API。由于图片是由浏览器自动加载的,所以每个查看过该文章的人都会不知不觉为其点赞。很显然,该用户利用了系统的CSRF漏洞实施刷赞, 这是网站开发人员始料未及的。

有人可能认为这仅仅是因为点赞API设计不理想导致的,应当使用POST请求,这样就能避免上面的场景。然而,当使用POST请求时,确实避免了如img、script、iframe等标签自动发起GET请求的问题,但这并不能杜绝CSRF攻击的发生。一些恶意网站会通过表单的形式构造攻击请求:

<form action="http://com.example.com/xxx/transfer" method="post"> 
	<input type="hidden" name="money" value="10000" />
	<input type="hidden" name="to" value="hacker" />
	<input type="submit" value="点击我查看美女图片" />
</form>

假如登录过某银行站点而没有注销,其间被诱导访问了带有类似攻击的页面,那么在该页面一旦单击按钮,很可能会导致在该银行的账户资金被直接转走。甚至根本不需要单击按钮,而是直接用 JavaScript代码自动化该过程。

CSRF利用了系统对登录期用户的信任,使得用户执行了某些并非意愿的操作从而造成损失。如
何真正地防范CSRF攻击,对每个有安全需求的系统而言都尤为重要。

2.CSRF的防御手段

一些工具可以检测系统是否存在 CSRF 漏洞,例如,CSRFTester,有兴趣的读者可以自行了解。

在任何情况下,都应当尽可能地避免以GET方式提供涉及数据修改的API。在此基础上,防御 CSRF攻击的方式主要有以下两种。

(1)HTTPReferer HTTP Referer

是由浏览器添加的一个请求头字段,用于标识请求来源,通常用在一些统计相关的 场景,浏览器端无法轻易篡改该值。

回到前面构造POST请求实行CSRF攻击的场景,其必要条件就是诱使用户跳转到第三方页面,在第三方页面构造发起的POST请求中,HTTP Referer字段不是银行的URL(少部分老版本的IE浏览器可以调用API进行伪造,但最后的执行逻辑是放在用户浏览器上的,只要用户的浏览器版本较新,便可以避免这个问题),当校验到请求来自其他站点时,可以认为是CSRF攻击,从而拒绝该服务。

当然,这种方式简单便捷,但并非完全可靠。除前面提到的部分浏览器可以篡改 HTTP Referer 外,如果用户在浏览器中设置了不被跟踪,那么HTTP Referer字段就不会自动添加,当合法用户访问时,系统会认为是CSRF攻击,从而拒绝访问。

(2)CsrfToken认证 

CSRF是利用用户的登录态进行攻击的,而用户的登录态记录在cookie中。其实攻击者并不知道用户的cookie存放了哪些数据,于是想方设法让用户自身发起请求,这样浏览器便会自行将cookie传送到服务器完成身份校验。

CsrfToken的防范思路是,添加一些并不存放于 cookie 的验证值,并在每个请求中都进行校验, 便可以阻止CSRF攻击。 具体做法是在用户登录时,由系统发放一个CsrfToken值,用户携带该CsrfToken值与用户名、密码等参数完成登录。系统记录该会话的CsrfToken 值,之后在用户的任何请求中,都必须带上该 CsrfToken值,并由系统进行校验。

这种方法需要与前端配合,包括存储CsrfToken值,以及在任何请求中(包括表单和Ajax)携带 CsrfToken值。安全性相较于HTTP Referer提高很多,但也存在一定的弊端。例如,在现有的系统中进行改造时,前端的工作量会非常大,几乎要对所有请求进行处理。如果都是XMLHttpRequest,则可以统一添加CsrfToken值;但如果存在大量的表单和a标签,就会变得非常烦琐。因此建议在系统开发之初考虑如何防御CSRF攻击。

3.使用Spring Security防御CSRF攻击

CSRF攻击完全是基于浏览器进行的,如果我们的系统前端并非在浏览器中运作,就应当关闭CSRFSpring Security通过注册一个CsrfFilter来专门处理CSRF攻击。

Spring Security中,CsrfToken是一个用于描述Token值,以及验证时应当获取哪个请求参数或请求头字段的接口。

public interface CsrfToken extends Serializable {

    String getHeaderName();

    String getParameterName();

    String getToken();
}

CsrfTokenRepository则定义了如何生成、保存以及加载CsrfToken。

public interface CsrfTokenRepository {

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值