目录

  • 一、什么是CSRF?
  • 二、演示CSRF攻击
    • 2.1.添加pom依赖
    • 2.2.添加UserDetailsService实现类
    • 2.3.添加security配置类
    • 2.4.添加控制器
    • 2.5.添加html
    • 2.6.创建攻击者项目
    • 2.7.测试
  • 三、防止CSRF攻击
    • 3.1.调整代码
    • 3.2.测试
  • 四、原理

注意:如果对SpringSecurity不是很了解的,一定要先去读我的这一篇文章,写的非常详细

https://blog.csdn.net/weixin_43888891/article/details/124111885

通过本篇文章可以学到以下三点:

  1. 通过代码示例来 演示CSRF攻击!
  2. 通过security给我们提供的保护机制,来进行防止CSRF攻击
  3. security防止CSRF的原理

下方代码的源码链接:https://gitee.com/gzl_com/spring-security

一、什么是CSRF?

跨站请求伪造(英语:Cross-site request forgery),也被称为 one-click attack 或者 session riding,通常缩写为 CSRF 或者 XSRF是一种挟制用户在当前已登录的 Web 应用程序上执行非本意的操作的攻击方法。跟跨网站脚本(XSS)相比,XSS利用的是用户对指定网站的信任,CSRF 利用的是网站对用户网页浏览器的信任

跨站请求攻击,简单地说,是攻击者通过一些技术手段欺骗用户的浏览器去访问一个自己曾经认证过的网站并运行一些操作(如发邮件,发消息,甚至财产操作如转账和购买商品)。由于浏览器曾经认证过,所以被访问的网站会认为是真正的用户操作而去运行。这利用了 web 中用户身份验证的一个漏洞:简单的身份验证只能保证请求发自某个用户的浏览器,却不能保证请求本身是用户自愿发出的

从 Spring Security 4.0 开始,默认情况下会启用 CSRF 保护,以防止 CSRF 攻击应用程序,Spring Security CSRF 会针对 PATCH,POST,PUT 和 DELETE 方法进行防护。

二、演示CSRF攻击

本案例直接演示假如我不开启CSRF保护会出现什么情况。

创建项目的过程就省略了,直接ider创建springboot项目即可。为了直观一点,这里我创建了两个项目,一个项目是我们自己的项目,另一个项目作为攻击者所在的服务器项目。

以下示例主要就是演示这一场景:

我通过账号密码登录了tb,然后这时候我没有关闭这个浏览器,又去浏览别的浏览器了,不知道怎么回事点击了一个广告进来了,而这个广告页面其实就是恶意的,他提前知道了tb修改密码的接口访问地址,然后在广告页面内嵌一个修改密码的地址,而我们并没有退出登录tb,也就意味着他是可以拿到认证的,可能我们随便一点击广告页面,然后触发接口,我们的淘宝密码就 被修改了,这就是整个被CSRF攻击的流程。

当然tb不可能这么low,人家有最牛的安全防护人员,这里只是拿他举例而已。

2.1.添加pom依赖

<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-security</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-thymeleaf</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.security</groupId><artifactId>spring-security-test</artifactId><scope>test</scope></dependency><!--对Thymeleaf添加Spring Security标签支持--><dependency><groupId>org.thymeleaf.extras</groupId><artifactId>thymeleaf-extras-springsecurity5</artifactId></dependency>
</dependencies>

2.2.添加UserDetailsService实现类

@Service
public class UserDetailsServiceImpl implements UserDetailsService {@Overridepublic UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {List<SimpleGrantedAuthority> list = new ArrayList<>();list.add(new SimpleGrantedAuthority("role"));UserDetails userDetails = new User("lucy", new BCryptPasswordEncoder().encode("123"), list);return userDetails;}
}

2.3.添加security配置类

这里一定要添加 http.csrf().disable(); 因为CSRF保护security默认是开启的,添加这个就是关闭CSRF保护的意思。

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {@ResourceUserDetailsService userDetailsService;//实现用户身份认证@Overrideprotected void configure(AuthenticationManagerBuilder auth) throws Exception {BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();auth.userDetailsService(userDetailsService).passwordEncoder(encoder);}@Overrideprotected void configure(HttpSecurity http) throws Exception {//配置url的访问权限http.authorizeRequests().antMatchers("/userLogin").permitAll().antMatchers("/login/**").permitAll().anyRequest().authenticated();//关闭csrf保护功能http.csrf().disable();//使用自定义的登录窗口http.formLogin().loginPage("/userLogin").permitAll().usernameParameter("username").passwordParameter("password").defaultSuccessUrl("/toUpdate").failureUrl("/userLogin?error");}
}

2.4.添加控制器

因为我们项目当中用到了Thymeleaf ,Thymeleaf 可以通过接口String返回的字符串,去寻找html。例如:/userLogin接口返回的字符串是login/login,他的意思就是我通过/userLogin请求实际上就是跳转到templates/login/login.html页面当中。

@Controller
public class LoginController {@GetMapping("/userLogin")public String login() {return "login/login";}@GetMapping("/toUpdate")public String test() {return "csrf/updateUser";}@PostMapping("/updatePassword")public String getToken(String username, String password) {System.out.println(username);System.out.println(password);System.out.println("修改密码成功");return "csrf/updateSuccess";}
}

2.5.添加html

一共三个html

updateSuccess.html

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
<head><meta charset="UTF-8"><title>用户修改</title>
</head>
<body>
<div>
<!--    <span th:text="${_csrf.token}"></span>-->修改成功
</div></body>
</html>

updateUser.html

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
<head><meta charset="UTF-8"><title>用户修改</title>
</head>
<body>
<div align="center"><form  method="post" action="updatePassword">
<!--      <input type="hidden" th:name="${_csrf.parameterName}" th:value="${_csrf.token}"/>-->用户名: <input type="text" name="username" /><br />密&nbsp;&nbsp;码: <input type="password" name="password" /><br /><button type="submit">修改</button></form>
</div>
</body>
</html>

login.html

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
<head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>用户登录界面</title>
</head>
<body class="text-center"><form class="form-signin" th:method="post" th:action="@{/userLogin}"><h1 class="h3 mb-3 font-weight-normal">请登录</h1><input type="text" class="form-control" placeholder="用户名" required="" autofocus="" name="username"><input type="password" class="form-control" placeholder="密码" required="" name="password"><button class="btn btn-lg btn-primary btn-block" type="submit" >登录</button></form>
</body>
</html>

2.6.创建攻击者项目

这个项目就是一个空项目,只有一个文件,就是模仿弹出来的广告。

pom依赖

<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-thymeleaf</artifactId></dependency>
</dependencies>

可能有的甚至会做一个假tb,当你不注意他的网址的时候以为是真的,然后点击进去输入了自己的个人信息等,一旦他掌握的有相关修改接口,后果不堪设想。

index.html

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
<head><meta charset="UTF-8"><title>用户修改</title>
</head>
<body>
<div align="center"><form  method="post" action="http://localhost:8080/updatePassword">用户名: <input type="text" name="username" /><br />密&nbsp;&nbsp;码: <input type="password" name="password" /><br /><button type="submit">修改</button></form>
</div>
</body>
</html>

通过application.properties配置当中修改端口号,避免和上面项目产生冲突

server.port=8081

2.7.测试

  1. http://localhost:8080/userLogin登录:账号lucy,密码123
  2. http://localhost:8081/ 不小心点开这个广告了
  3. 然后通过8081端口的网址输入账号密码,直接密码被修改了


三、防止CSRF攻击

3.1.调整代码

1.在登录页面添加一个隐藏域:

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


2.关闭安全配置的类中的 csrf

// http.csrf().disable();


3.可以把这个注释放开,当修改成功跳转到这个页面的时候,我们看一下_csrf.token到底是什么

3.2.测试

这时候使用8080登录后,通过8081去修改是直接报403的。

四、原理

这个value值是随机生成的,而这时病毒网站可以窃取到用户唯一标识,却无法知道给该用户的随机token,这就能防止csrf攻击所造成的影响。

完成CSRF防护的 核心 就是 CsrfFilter 当中的doFilterInternal方法。


完整流程:

  1. 他的流程就是登录的时候生成token,然后传到request域中,并且session当中也会保存一份
  2. 然后html页面访问接口的时候需要从域当中取到token值,以Header或者Parameter的形式传入到后端
  3. 后端拿到这个token值的时候,每次请求会和session当中的token进行比较

通过上面得知tokenRepository实现类很重要,他决定了token保存位置。默认是存储到session。


上面csrfFilter当中有个matches方法,他的作用就是如下请求方式的请求不做CSRF防护。

SpringBoot+SpringSecurity+Thymeleaf 演示CSRF攻击相关推荐

  1. SpringBoot 如何防御 CSRF 攻击?

    作者 | 江南一点雨      责编 | 欧阳姝黎 CSRF 就是跨域请求伪造,英文全称是 Cross Site Request Forgery. 这是一种非常常见的 Web 攻击方式,其实是很好防御 ...

  2. csrf攻击与防护—2用flask简单演示防范csrf攻击之referer

    接上篇 csrf攻击与防护-1用flask简单演示csrf攻击 以下是根据referer字段防止csrf攻击的新代码: bank.py import uuid from flask import re ...

  3. Springboot和Angular的CSRF防御

    CSRF 是什么 跨站请求伪造 知乎解答搬运: csrf是什么. 参考文章:SpringSecurity的防Csrf攻击. Springboot CSRF 在spring boot中可以使用sprin ...

  4. PHP开发中csrf攻击的简单演示和防范

    CSRF的全名为Cross-site request forgery,它的中文名为 跨站请求伪造(伪造跨站请求[这样读顺口一点])CSRF是一种夹持用户在已经登陆的web应用程序上执行非本意的操作的攻 ...

  5. springboot 、thymeleaf、pagehelper 、springsecurity实现 登录,用户认证,分页的前端使用妹子UI

    springboot  .thymeleaf.pagehelper .springsecurity 实现 登录,用户认证,分页的前端使用妹子UIhttp://tpl.amazeui.org/. 项目下 ...

  6. html jwt权限控制,SpringBoot+SpringSecurity+JWT实RESTfulAPI权限控制

    在整合jwt之前,我们首先要在SpringBoot中整合security的模块,来实现基于security的授权控制.用过security的人都知道,它的功能无比的强大比shiro还要强大,但是今天我 ...

  7. springboot+springsecurity基于用户表-角色表-权限表的权限控制(三)

    用户实体类 参考:springboot+springsecurity基于角色的权限验证(二) 配置类 @Configuration @EnableWebSecurity @EnableGlobalMe ...

  8. SpringBoot+SpringSecurity+JWT实现认证和授权

    SprinBoot 系列文章: Spring Boot入门之Hello Spring Boot SpringBoot 配置多个JdbcTemplate SpringBoot 整合Mybatis CAS ...

  9. spring boot构建基础版web项目(一)springboot、thymeleaf控制层基础构

    原文作者:弥诺R 原文地址:http://www.minuor.com/147852147/article 转载声明:转载请注明原文地址,注意版权维护,谢谢! 写前说明 根据个人在各篇博文中看到的信息 ...

最新文章

  1. 编写一个程序,它从标准输入(终端)读取C源代码,并验证所有的花括号都正确的成对出现。...
  2. 系统下装软件_电力二次设备自动测试系统
  3. 天池大赛通用目标检测的对抗攻击方法一览
  4. 直播 | 平安人寿资深算法工程师姚晓远:对话生成模型的探析与创新
  5. xxljob 配置具体定时任务_分布式任务调度: XXL-Job
  6. 机器学习 —— 概率图模型(推理:采样算法)
  7. 开课吧学python靠谱吗-学设计?学Python?看看我的人生是如何开挂!!!
  8. 2000坐标系转经纬度工具_【Leaflet开发】L.CRS + 搞定Leaflet多坐标系拓展
  9. JPYXGSIT故障解决方案
  10. 流水线上的农民:我在工厂种蔬菜
  11. keilC51和MDK_ARM的安装与兼容及LED点亮实验
  12. C语言-书籍资料汇总
  13. 加仓减仓口诀_加仓减仓口诀
  14. 如何发表SCI论文?写SCI文章的心得
  15. 关于通用人工智能的思考
  16. 给新程序员的10条建议
  17. ZynqMP Vitis PS加载PL代码
  18. git上如何删除仓库
  19. 18、iOS底层分析 - GCD(一)基本概念与简单使用
  20. 201911-202004《JavaScript设计模式》读书笔记

热门文章

  1. webscraper多页爬取_webscraper的常见爬取问题
  2. 每天数千个漏洞被公开 选什么工具能让漏洞追不上我?RASP介绍
  3. 【Bash百宝箱】Makefile快速入门
  4. Pumpkin Garden 靶场实战
  5. Pandas常见筛选数据的五种方法其一逻辑筛选。看见必懂,懂者必会,会者必加分
  6. android支付宝系统繁忙,支付宝支付 系统繁忙,请稍后再试 62008 难道没人碰到过吗...
  7. phpwind9.0 read.php 修改,phpwind9.0模板制作教程——制作论坛风格
  8. 绪论(数据结构-邓俊辉)
  9. Windows10系统 ADMUI3无法删除
  10. 8255实现数码显示管显示两位数字