SpringSecurity之CSRF漏洞保护

本文详细介绍了CSRF攻击的概念,它利用用户浏览器的已登录状态,伪装成用户发起恶意请求。通过举例展示了攻击过程,并讨论了CSRF防御的核心策略——令牌同步模式,即在每个请求中携带CSRF令牌,服务端验证令牌以防止恶意请求。同时,文章给出了在SpringSecurity中启用CSRF防御的代码示例,并分别针对传统Web开发和前后端分离场景提出了实现CSRF防御的方法。
摘要由CSDN通过智能技术生成

1.csrf简介

CSRF(Cross-Site Request Forgery跨站请求伪造),也可称为一键式攻击(one-click-attack),通常缩写为CSRF或者XSRF

CSRF攻击是一种挟持用户在当前已登录的浏览器上发送恶意请求的攻击方法。相对于XSS利用用户对指定网站的信任,CSRF则是利用网站对用户网页浏览器的信任。简单来说,SCRF是攻击者通过一些技术手段欺骗用户的浏览器,去访问一个用户曾经认证过的网站并执行恶意请求,例如发送邮件、发消息、甚至财产操作(如转账和购买商品)。由于客户端(浏览器)已经在该网站上认证过,所以该网站会认为是真正用户在操作而执行请求(实际上这个并非用户的本意)。

例子

假设zkt现在登录了某银行的网站准备完成一项转账操作,转账的链接如下:

https://bank.xxx.com/withdrwa?account=zkt&amount=1000for=zhangsan

可以看到,这个连接是想从zkt这个账户下转账1000元到张三账户下,假设zkt没有注销登录该银行的网站,就在同一个浏览器新的选项卡中打开了一个危险网站,这个危险网站中有一幅图片,代码如下:

一旦用户打开了这个网站,这个图片链接中的请求就会被发送出去。由于是同一个浏览器并且用户尚未注销登录,所以该请求会自动携带上对应的有效的cookie信息,进而完成一次转账操作。这就是跨站请求伪造。

2.csrf防御

CSRF攻击的根源在于浏览器默认的身份验证机制(自动携带当前网站的Cookie信息),这种机制虽然可以保证请求是来自用户的某个浏览器,但是无法确保这请求是用户授权发送。攻击者和用户发送的请求一模一样,这意味着我们没有办法去直接拒绝这里的某一个请求。如果能在合法请求中额外携带一个攻击者无法获取的参数,就可以成功区分出两种不同的请求,进而直接拒绝掉恶意请求。在SpringSecurity中就提供了这种机制来防御CSRF攻击,这种机制我们称之为令牌同步模式

3.令牌同步模式

这是目前主流的CSRF攻击防御方案。具体的操作方式就是在每一个HTTP请求中,除了默认自动携带的Cookie参数之外,再提供一个安全的、随机生成的字符串,我们称之为CSRF令牌。这个CSRF令牌由服务端生成,生成后再HttpSession中保存一份。当前端请求到达后,将请求携带的CSRF令牌信息和服务端中保存的令牌进行对比,如果两者不相等,则拒绝掉该HTTP请求。

注意:考虑到会有一些外部站点链接到我们的网站,所以我们要求请求是幂等的,这样对于HEAD、OPTIONS、TRACE等方法就没有必要使用CSRF令牌了,强行使用可能会导致令牌泄露。

4.开启CSRF防御

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeHttpRequests()
                .anyRequest().authenticated()
                .and()
                .formLogin()
                .and()
                .csrf();  //开启csrf
    }

5.传统Web开发使用CSRF防御

开启CSRF防御后会自动在提交的表单中加入如下代码,如果不能自动加入,需要在开启之后手动加入如下代码,并随着请求提交。获取服务端令牌方式如下:

<input type="hidden" th:name="${_csrf.parameterName}"
th:value="${_csrf.token}"/>

6.前后端分离使用CSRF防御

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
	//...


    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeHttpRequests()
                .anyRequest().authenticated()
                .and()
                .formLogin()
                .and()
                .csrf()//开启csrf
//                .disable();
                .csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse());  //将令牌保存到cookie中 允许cookie前端获取

        http.addFilterAt(loginFilter(), UsernamePasswordAuthenticationFilter.class);
    }
}

访问登录界面查看cookie

在这里插入图片描述

发送请求携带令牌即可

  • 请求参数中携带令牌
key: "_csrf"
value: "xxx"
  • 请求头中携带令牌
X-XSRF-TOKEN:value

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值