松哥手把手教你在 SpringBoot 中防御 CSRF 攻击!so easy!

CSRF 就是跨域请求伪造,英文全称是 Cross Site Request Forgery。

这是一种非常常见的 Web 攻击方式,其实是很好防御的,但是由于经常被很多开发者忽略,进而导致很多网站实际上都存在 CSRF 攻击的安全隐患。

今天松哥就来和大家聊一聊什么是 CSRF 攻击以及 CSRF 攻击该如何防御。

本文是本系列第 18 篇,阅读本系列前面文章有助于更好的理解本文:

  1. 挖一个大坑,Spring Security 开搞!

  2. 松哥手把手带你入门 Spring Security,别再问密码怎么解密了

  3. 手把手教你定制 Spring Security 中的表单登录

  4. Spring Security 做前后端分离,咱就别做页面跳转了!统统 JSON 交互

  5. Spring Security 中的授权操作原来这么简单

  6. Spring Security 如何将用户数据存入数据库?

  7. Spring Security+Spring Data Jpa 强强联手,安全管理只有更简单!

  8. Spring Boot + Spring Security 实现自动登录功能

  9. Spring Boot 自动登录,安全风险要怎么控制?

  10. 在微服务项目中,Spring Security 比 Shiro 强在哪?

  11. SpringSecurity 自定义认证逻辑的两种方式(高级玩法)

  12. Spring Security 中如何快速查看登录用户 IP 地址等信息?

  13. Spring Security 自动踢掉前一个登录用户,一个配置搞定!

  14. Spring Boot + Vue 前后端分离项目,如何踢掉已登录用户?

  15. Spring Security 自带防火墙!你都不知道自己的系统有多安全!

  16. 什么是会话固定攻击?Spring Boot 中要如何防御会话固定攻击?

  17. 集群化部署,Spring Security 要如何处理 session 共享?

1.CSRF原理


想要防御 CSRF 攻击,那我们得先搞清楚什么是 CSRF 攻击,松哥通过下面一张图,来和大家梳理 CSRF 攻击流程:

其实这个流程很简单:

  1. 假设用户打开了招商银行网上银行网站,并且登录。

  2. 登录成功后,网上银行会返回 Cookie 给前端,浏览器将 Cookie 保存下来。

  3. 用户在没有登出网上银行的情况下,在浏览器里边打开了一个新的选项卡,然后又去访问了一个危险网站。

  4. 这个危险网站上有一个超链接,超链接的地址指向了招商银行网上银行。

  5. 用户点击了这个超链接,由于这个超链接会自动携带上浏览器中保存的 Cookie,所以用户不知不觉中就访问了网上银行,进而可能给自己造成了损失。

CSRF 的流程大致就是这样,接下来松哥用一个简单的例子和小伙伴们展示一下 CSRF 到底是怎么回事。

2.CSRF实践


接下来,我创建一个名为 csrf-1 的 Spring Boot 项目,这个项目相当于我们上面所说的网上银行网站,创建项目时引入 Web 和 Spring Security 依赖,如下:

创建成功后,方便起见,我们直接将 Spring Security 用户名/密码 配置在 application.properties 文件中:

spring.security.user.name=javaboy

spring.security.user.password=123

然后我们提供两个测试接口:

@RestController

public class HelloController {

@PostMapping(“/transfer”)

public void transferMoney(String name, Integer money) {

System.out.println("name = " + name);

System.out.println("money = " + money);

}

@GetMapping(“/hello”)

public String hello() {

return “hello”;

}

}

假设 /transfer 是一个转账接口(这里是假设,主要是给大家演示 CSRF 攻击,真实的转账接口比这复杂)。

最后我们还需要配置一下 Spring Security,因为 Spring Security 中默认是可以自动防御 CSRF 攻击的,所以我们要把这个关闭掉:

@Configuration

public class SecurityConfig extends WebSecurityConfigurerAdapter {

@Override

protected void configure(HttpSecurity http) throws Exception {

http.authorizeRequests().anyRequest().authenticated()

.and()

.formLogin()

.and()

.csrf()

.disable();

}

}

配置完成后,我们启动 csrf-1 项目。

接下来,我们再创建一个 csrf-2 项目,这个项目相当于是一个危险网站,为了方便,这里创建时我们只需要引入 web 依赖即可。

项目创建成功后,首先修改项目端口:

server.port=8081

然后我们在 resources/static 目录下创建一个 hello.html ,内容如下:

这里有一个超链接,超链接的文本是点击查看美女图片,当你点击了超链接之后,会自动请求 http://localhost:8080/transfer 接口,同时隐藏域还携带了两个参数。

配置完成后,就可以启动 csrf-2 项目了。

接下来,用户首先访问 csrf-1 项目中的接口,在访问的时候需要登录,用户就执行了登录操作,访问完整后,用户并没有执行登出操作,然后用户访问 csrf-2 中的页面,看到了超链接,好奇这美女到底长啥样,一点击,结果钱就被人转走了。

3.CSRF防御


先来说说防御思路。

CSRF 防御,一个核心思路就是在前端请求中,添加一个随机数。

因为在 CSRF 攻击中,黑客网站其实是不知道用户的 Cookie 具体是什么的,他是让用户自己发送请求到网上银行这个网站的,因为这个过程会自动携带上 Cookie 中的信息。

所以我们的防御思路是这样:用户在访问网上银行时,除了携带 Cookie 中的信息之外,还需要携带一个随机数,如果用户没有携带这个随机数,则网上银行网站会拒绝该请求。黑客网站诱导用户点击超链接时,会自动携带上 Cookie 中的信息,但是却不会自动携带随机数,这样就成功的避免掉 CSRF 攻击了。

Spring Security 中对此提供了很好的支持,我们一起来看下。

3.1 默认方案

Spring Security 中默认实际上就提供了 csrf 防御,但是需要开发者做的事情比较多。

首先我们来创建一个新的 Spring Boot 工程,创建时引入 Spring Security、Thymeleaf 和 web 依赖。

项目创建成功后,我们还是在 application.properties 中配置用户名/密码:

spring.security.user.name=javaboy

spring.security.user.password=123

接下来,我们提供一个测试接口:

@Controller

public class HelloController {

@PostMapping(“/hello”)

@ResponseBody

public String hello() {

return “hello”;

}

}

注意,这个测试接口是一个 POST 请求,因为默认情况下,GET、HEAD、TRACE 以及 OPTIONS 是不需要验证 CSRF 攻击的。

然后,我们在 resources/templates 目录下,新建一个 thymeleaf 模版,如下:

注意,在发送 POST 请求的时候,还额外携带了一个隐藏域,隐藏域的 key 是 ${_csrf.parameterName},value 则是 ${_csrf.token}

这两个值服务端会自动带过来,我们只需要在前端渲染出来即可。

接下来给前端 hello.html 页面添加一个控制器,如下:

@GetMapping(“/hello”)

public String hello2() {

return “hello”;

}

笔者福利

以下是小编自己针对马上即将到来的金九银十准备的一套“面试宝典”,不管是技术还是HR的问题都有针对性的回答。

有了这个,面试踩雷?不存在的!

回馈粉丝,诚意满满!!!




l 页面添加一个控制器,如下:

@GetMapping(“/hello”)

public String hello2() {

return “hello”;

}

笔者福利

以下是小编自己针对马上即将到来的金九银十准备的一套“面试宝典”,不管是技术还是HR的问题都有针对性的回答。

有了这个,面试踩雷?不存在的!

回馈粉丝,诚意满满!!!

[外链图片转存中…(img-pUTajEUC-1714731055364)]
[外链图片转存中…(img-JuILbD1h-1714731055365)]
[外链图片转存中…(img-tXEfevPB-1714731055365)]
[外链图片转存中…(img-XVFEB0kZ-1714731055366)]

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

  • 15
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
引用\[1\]:微人事是一个前后端分离的人力资源管理系统,项目采用 SpringBoot + Vue 开发。项目打通了前后端,并且提供了非常详尽的文档,从 Spring Boot 接口设计到前端 Vue 的开发思路,作者全部都记录在项目的 wiki ,是不可多得的 Java 全栈学习资料。引用\[2\]:其实前后端分离本身并不难,后段提供接口,前端做数据展示,关键是这种思想。很多人做惯了前后端不分的开发,在做前后端分离的时候,很容易带进来一些前后端不分时候的开发思路,结果做出来的产品不伦不类,因此松哥这里给大家整理了几个开源的前后端分离项目,帮助大家快速掌握前后端分离开发技术栈。美人鱼 star 数 3499项目地址: https://gitee.com/mumu-osc/NiceFish。引用\[3\]:听名字就知道这是个不错的项目,事实上确实不赖。NiceFish(美人鱼) 是一个系列项目,目标是示范前后端分离的开发模式:前端浏览器、移动端、Electron 环境的各种开发模式;后端有两个版本:SpringBoot 版本和 SpringCloud 版本,前端有 Angular 、React 以及 Electron 等版本。 针对您的问题,如果您想了解关于SpringBoot后端分离的项目,可以考虑微人事和NiceFish这两个项目。微人事是一个人力资源管理系统,采用了SpringBoot和Vue进行开发,项目提供了详尽的文档,记录了从Spring Boot接口设计到前端Vue开发的思路,是一个非常有价值的Java全栈学习资料。而NiceFish是一个系列项目,旨在示范前后端分离的开发模式,包括前端浏览器、移动端和Electron环境的各种开发模式,后端SpringBoot版本和SpringCloud版本,前端有Angular、React和Electron等版本。这些项目都是开源的,可以帮助您快速掌握前后端分离开发技术栈。 #### 引用[.reference_title] - *1* *2* *3* [七个开源的 Spring Boot后端分离项目,一定要收藏!](https://blog.csdn.net/u012702547/article/details/100973824)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^koosearch_v1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值