当前位置: 首页 > news >正文

07CSRF 漏洞保护

目录

本节大纲

一、简介

二、CSRF攻击演示

1. 创建银行应用

2. 创建恶意应用

三、CSRF 防御

1. 令牌同步模式

2. 开启 CSRF 防御

3. 查看登录页面源码

四、传统web开发使用CSRF

1. 开发测试 controller

2. 创建 html

3. 测试查看index.html源码

五、前后端分离使用 CSRF

1. 修改 CSRF 存入 Cookie

2. 访问登录界面查看 cookie

3. 发送请求携带令牌即可


本节大纲

  • CSRF 简介
  • CSRF 防御&基本配置
  • 实战

一、简介

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

为 CSRF 或者 XSRF。

CSRF 攻击是一种挟持用户在当前已登录的浏览器上发送恶意请求的攻击方法。相对于XSS利用用户对指定

网站的信任,CSRF则是利用网站对用户网页浏览器的信任。

简单来说,CSRF是致击者通过一些技术手段欺骗用户的浏览器,去访问一个用户曾经认证过的网站并执行

恶意请求,例如发送邮件、发消息、甚至财产操作 (如转账和购买商品)。由于客户端(浏览器)已经在该网

站上认证过,所以该网站会认为是真正用户在操作而执行请求(实际上这个并非用户的本意)。

举个简单的例子:

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

https: //bank .xxx .com/withdraw?account=blr&amount=1000&for=zhangsan

可以看到,这个链接是想从 blr 这个账户下转账 1000 元到 zhangsan 账户下,假设blr 没有注销登录该银

行的网站,就在同一个浏览器新的选项卡中打开了一个危险网站,这个危险网站中有一幅图片,代码如

下:

一旦用户打开了这个网站,这个图片链接中的请求就会自动发送出去。由于是同一个浏览器并且用户尚未

注销登录,所以该请求会自动携带上对应的有效的 Cookie 信息,进而完成一次转账操作。这就是跨站请

求伪造。

二、CSRF攻击演示

1. 创建银行应用

  • 引入依赖
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId>
</dependency>

  • 修改配置
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {@Beanpublic UserDetailsService userDetailsService() {InMemoryUserDetailsManager inMemoryUserDetailsManager = new InMemoryUserDetailsManager();inMemoryUserDetailsManager.createUser(User.withUsername("root").password("{noop}123").roles("admin").build());return inMemoryUserDetailsManager;}@Overrideprotected void configure(AuthenticationManagerBuilder auth) throws Exception {auth.userDetailsService(userDetailsService());}@Overrideprotected void configure(HttpSecurity http) throws Exception {http.authorizeRequests().anyRequest().authenticated().and().formLogin().and().csrf().disable();}
}
  • 创建 controller 并启动启动
@RestController
public class HelloController {@PostMapping("/withdraw")public String withdraw() {System.out.println("执行一次转账操作");return "执行一次转账操作";}
}

2. 创建恶意应用

  • 创建简单 springboot 应用
  • 修改配置
server:port: 8081
  • 准备攻击页面
<form action="http://127.0.0.1:8080/withdraw" method="post"><input name="name" type="hidden" value="blr"/><input name="money" type="hidden" value="10000"><input type="submit" value="点我">
</form>

三、CSRF 防御

CSRF攻击的根源在于浏览器默认的身份验证机制(自动携带当前网站的Cookie信息),这种机制虽然可以保

证请求是来自用户的某个浏览器,但是无法确保这请求是用户授权发送。攻击者和用户发送的请求一模一

样,这意味着我们没有办法去直接拒绝这里的某一个请求。

如果能在合法清求中额外携带一个攻击者无法获取的参数,就可以成功区分出两种不同的请求,进而直接

拒绝掉恶意请求。

在 SpringSecurity 中就提供了这种机制来防御 CSRF 攻击,这种机制我们称之为令牌同步模式。

1. 令牌同步模式

这是目前主流的 CSRF 攻击防御方案。具体的操作方式就是在每一个 HTTP 请求中,除了默认自动携带的

Cookie 参数之外,再提供一个安全的、随机生成的宇符串,我们称之为 CSRF 令牌。这个 CSRF 令牌由服

务端生成,生成后在 HtpSession 中保存一份。

当前端请求到达后,将请求携带的 CSRF 令牌信息和服务端中保存的令牌进行对比,如果两者不相等,则

拒绝掉该 HITTP 请求。

注意:考虑到会有一些外部站点链接到我们的网站,所以我们要求请求是幂等的,这样对子HEAD、

OPTIONS、TRACE 等方法就没有

必要使用 CSRF 令牌了,强行使用可能会导致令牌泄露!

2. 开启 CSRF 防御

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {@Overrideprotected void configure(HttpSecurity http) throws Exception {http....formLogin().and().csrf(); //开启 csrf}
}

3. 查看登录页面源码

四、传统web开发使用CSRF

开启CSRF防御后会自动在提交的表单中加入如下代码,如果不能自动加入,需要在开启之后手动加入如下

代码,并随着请求提交。

获取服务端令牌方式如下:

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

1. 开发测试 controller

@Controller
public class HelloController {@PostMapping("/hello")@ResponseBodypublic String hello() {System.out.println("hello success");return "hello success";}@GetMapping("/index.html")public String index() {return "index";}
}

2. 创建 html

<html lang="en">
<head><meta charset="UTF-8"><title>测试 CSRF 防御</title>
</head>
<body>
<form th:action="@{/hello}" method="post"><input type="submit" value="hello"/>
</form>
</body>
</html>

3. 测试查看index.html源码

五、前后端分离使用 CSRF

前后端分离开发时,只需要将生成 csrf 放入到cookie 中,

并在请求时获取 cookie 中令牌信息进行提交即可。

1. 修改 CSRF 存入 Cookie

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {@Overrideprotected void configure(HttpSecurity http) throws Exception {http.authorizeRequests().anyRequest().authenticated().and().formLogin().and().csrf().csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse());}
}

2. 访问登录界面查看 cookie

3. 发送请求携带令牌即可

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

http://www.lryc.cn/news/578522.html

相关文章:

  • 事件监听器 + 回调处理器的事件循环系统
  • OpenCV CUDA模块设备层-----二值化阈值操作函数thresh_binary_func()
  • 设计模式精讲 Day 21:策略模式(Strategy Pattern)
  • 【STM32】 STM32低功耗模式详解:睡眠模式与唤醒机制【待测试】
  • 单元测试详解
  • 记录一个 Linux中脚本无法执行的问题
  • 构建淘宝评论监控系统:API 接口开发与实时数据采集教程
  • Camera相机人脸识别系列专题分析之十五:人脸特征检测FFD算法之libcvface_api.so算法API详细注释解析
  • Docker制作python环境
  • C++ 11 中 condition_variable 的探索与实践
  • 当足球遇上AI:赛事分析、伤病预测与智能裁判的崛起
  • postman入门篇
  • RabbitMQ - SpringAMQP及Work模型
  • k8s将service的IP对应的不同端口分配到不同的pod上
  • Vue 3 中的 `h` 函数详解
  • CAD文件处理控件Aspose.CAD教程:使用 Python 将绘图转换为 Photoshop
  • 【Python】字典get方法介绍
  • 面试拷打-20250701
  • 计网学习笔记第1章 计算机网络体系结构(灰灰题库)
  • 论文阅读笔记 NoPoSplat
  • 笔记/计算机网络
  • 动手学深度学习13.5. 多尺度目标检测-笔记练习(PyTorch)
  • 推客系统小程序终极指南:从0到1构建自动裂变增长引擎,实现业绩10倍增长!
  • (JAVA)自建应用调用企业微信API接口,实现消息推送
  • uniapp+vue写小程序页面,实现一张图片默认放大后,可以在容器内上下左右拖动查看
  • android13 如何定时输出app的帧率FPS
  • 应急响应类题练习——玄机第五章 Windows 实战-evtx 文件分析
  • mac重复文件清理,摄影师同款清理方案
  • COCO、VOC 和 YOLO三种主流目标检测数据格式的详细对比与示例说明
  • Java Selenium反爬虫技术方案