当前位置:

首页 > 编程开发 > SpringBoot防御CSRF攻击的流程及原理是什么

SpringBoot防御CSRF攻击的流程及原理是什么

CSRF原理想要防御CSRF攻击,那我们需要先搞清楚什么是CSRF攻击,通过下面图例来和大家梳理CSRF攻击流程:其实这个流程很简单:1.假设用户打开了招商网上银行网站,并且登录。2.登录成功后,网上银行会返回Cookie给前端,浏览器将Cookie保存下来。3.用户在没有登出网上银行的情况下,在浏览器里打开了一个新的选项卡,然后又去访问了一个危险网站。4.这个危险网站上有一个超链接,超链接的地址指向了招商网上银行。4.用户点击了这个链接,由于这个超链接会自动携带上浏览器中保存的Cookie,所以用户不知

本文目录

    CSRF 原理

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

    SpringBoot防御CSRF攻击的流程及原理是什么

    其实这个流程很简单:
    1.假设用户打开了招商网上银行网站,并且登录。
    2.登录成功后,网上银行会返回Cookie给前端,浏览器将Cookie保存下来。
    3.用户在没有登出网上银行的情况下,在浏览器里打开了一个新的选项卡,然后又去访问了一个危险网站。
    4.这个危险网站上有一个超链接,超链接的地址指向了招商网上银行。
    4.用户点击了这个链接,由于这个超链接会自动携带上浏览器中保存的Cookie,所以用户不知不觉中就访问了网上银行,进而可能给自己造成了损失。

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

    CSRF实践

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

    
    	
    		org.springframework.boot
    		spring-boot-starter-security
    	
    	
    		org.springframework.boot
    		spring-boot-starter-web
    	
    

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

    server.port= 8866
    spring.security.user.name=javaboy
    spring.security.user.password=123

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

    package com.mry.csrf.controller;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.PostMapping;
    import org.springframework.web.bind.annotation.RestController;
    @RestController
    public class CsrfDemoController {
        @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 攻击,真实的转账接口比这复杂)。

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

    package com.mry.csrf.config;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.security.config.annotation.web.builders.HttpSecurity;
    import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
    @Configuration
    public class SecurityConfig extends WebSecurityConfigurerAdapter {
        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http.authorizeRequests().anyRequest().authenticated()
                    .and()
                    .formLogin()
                    .and()
                    .csrf()
                    .disable();
        }
    }

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

    5.我们再创建一个 csrf-loophole-web 项目,这个项目相当于是一个危险网站,为了方便,这里创建时我们只需要引入 web 依赖即可。
    项目创建成功后,首先修改项目端口:

    server.port= 8855

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

    
    
    
        
        Title
    
    
        
            
            
            
        
    
    

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

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

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

    CSRF防御

    先来说说防御思路。

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

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

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

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

    前后端不分离方案

    Spring Security 中默认实际上就提供了 csrf 防御,但是需要开发者做的事情比较多。
    首先我们来创建一个新的 Spring Boot 工程,创建时引入 Spring Security、Thymeleaf 和 web 依赖。

    1.pom信息

    
    	
    		org.springframework.boot
    		spring-boot-starter-web
    	
    	
    		org.springframework.boot
    		spring-boot-starter-security
    	
    	
    		org.springframework.boot
    		spring-boot-starter-thymeleaf
    	
    	
    		org.springframework.boot
    		spring-boot-starter-test
    		test
    	
    

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

    spring.security.user.name=mry
    spring.security.user.password=123456

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

    package com.mry.csrf.controller;
    import org.springframework.web.bind.annotation.PostMapping;
    import org.springframework.web.bind.annotation.ResponseBody;
    import org.springframework.web.bind.annotation.RestController;
    @RestController
    public class SecurityCsrfController {
        @PostMapping("/hello")
        @ResponseBody
        public String hello() {
            return "hello";
        }
    }

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

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

    
    
    
    
        
        Title
    
    
        
            
            
        
    
    

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

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

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

    @GetMapping("/hello")
    public String hello2() {
    	return "hello";
    }

    6.添加完成后,启动项目,我们访问 hello 页面,在访问时候,需要先登录,登录成功之后,我们可以看到登录请求中也多了一个参数

    SpringBoot防御CSRF攻击的流程及原理是什么

    这里我们用了 Spring Security 的默认登录页面,如果大家使用自定义登录页面,可以参考上面 hello.html 的写法,通过一个隐藏域传递 _csrf 参数。

    访问到 hello 页面之后,再去点击【hello】按钮,就可以访问到 hello 接口了。

    SpringBoot防御CSRF攻击的流程及原理是什么

    这是 Spring Security 中默认的方案,通过 Model 将相关的数据带到前端来。

    如果你的项目是前后端不分项目,这种方案就可以了,如果你的项目是前后端分离项目,这种方案很明显不够用。

    前后端分离方案

    如果是前后端分离项目,Spring Security 也提供了解决方案。
    这次不是将 _csrf 放在 Model 中返回前端了,而是放在 Cookie 中返回前端,配置方式如下:

    package com.mry.csrf.config;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.security.config.annotation.web.builders.HttpSecurity;
    import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
    import org.springframework.security.web.csrf.CookieCsrfTokenRepository;
    @Configuration
    public class SecurityConfig extends WebSecurityConfigurerAdapter {
        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http.authorizeRequests().anyRequest().authenticated()
                    .and()
                    .formLogin()
                    .and()
                    .csrf().csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse());
        }
    }

    有小伙伴可能会说放在 Cookie 中不是又被黑客网站盗用了吗?其实不会的,大家注意如下两个问题:
    (1)黑客网站根本不知道你的 Cookie 里边存的啥,他也不需要知道,因为 CSRF 攻击是浏览器自动携带上 Cookie 中的数据的。
    (2)我们将服务端生成的随机数放在 Cookie 中,前端需要从 Cookie 中自己提取出来 _csrf 参数,然后拼接成参数传递给后端,单纯的将 Cookie 中的数据传到服务端是没用的。
    理解透了上面两点,你就会发现 _csrf 放在 Cookie 中是没有问题的,但是大家注意,配置的时候我们通过 withHttpOnlyFalse 方法获取了 CookieCsrfTokenRepository 的实例,该方法会设置 Cookie 中的 HttpOnly 属性为 false,也就是允许前端通过 js 操作 Cookie(否则你就没有办法获取到 _csrf)。

    配置完成后,重启项目,此时我们就发现返回的 Cookie 中多了一项:

    SpringBoot防御CSRF攻击的流程及原理是什么

    接下来,我们通过自定义登录页面,来看看前端要如何操作。

    首先我们在 resources/static 目录下新建一个 html 页面叫做 login.html:

    
    
    
        
        Title
        
        
    
    
    
                  

    这段 html 给大家解释一下:
    (1)首先引入 jquery 和 jquery.cookie ,方便我们一会操作 Cookie。
    (2)定义三个 input,前两个是用户名和密码,第三个是登录按钮。
    (3)点击登录按钮之后,我们先从 Cookie 中提取出 XSRF-TOKEN,这也就是我们要上传的 csrf 参数。
    (4)通过一个 POST 请求执行登录操作,注意携带上 _csrf 参数。

    服务端我们也稍作修改,如下:

    package com.mry.csrf.config;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.security.config.annotation.web.builders.HttpSecurity;
    import org.springframework.security.config.annotation.web.builders.WebSecurity;
    import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
    import org.springframework.security.web.csrf.CookieCsrfTokenRepository;
    @Configuration
    public class SecurityConfig extends WebSecurityConfigurerAdapter {
        @Override
        public void configure(WebSecurity web) throws Exception {
            web.ignoring().antMatchers("/static/js/**");
        }
        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http.authorizeRequests().anyRequest().authenticated()
                    .and()
                    .formLogin()
                    .loginPage("/login.html")
                    .successHandler((req,resp,authentication)->{
                        resp.getWriter().write("success");
                    })
                    .permitAll()
                    .and()
                    .csrf().csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse());
        }
    }

    一方面这里给 js 文件放行。

    另一方面配置一下登录页面,以及登录成功的回调,这里简单期间,登录成功的回调我就给一个字符串就可以了。在登录成功后回调的详细解释。

    OK,所有事情做完之后,我们访问 login.html 页面,输入用户名密码进行登录,结果如下:

    SpringBoot防御CSRF攻击的流程及原理是什么

    可以看到,我们的 _csrf 配置已经生效了。

    本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系bd@zhengruan.com
    作者最新文章
    编程开发
    相关文章 更多
    PHP 框架安全指南:如何防止 CSRF 攻击?
    PHP 框架安全指南:如何防止 CSRF 攻击?

    PHP框架安全指南:如何防止CSRF攻击?跨站点请求伪造(CSRF)攻击是一种网络攻击,其中攻击者诱骗用户在受害者的网络应用程序中执行非预期操作。CSRF如何工作?CSRF攻击利用了一个事实:大多数Web应用程序允许在同一个域名内不同页面之间发送请求。攻击者创建恶意页面,该页面向受害者的应用程序发送请求,触发未经授权的操作。如何防止CSRF攻击?1.使用反CSRF令牌:向每个用户分配一个唯一的令牌,将其存储在会话或Cookie中。在应用程序中包含一个隐藏字段,用于提交该令牌

    如何使用PHP防止跨站点请求伪造攻击
    如何使用PHP防止跨站点请求伪造攻击

    跨站点请求伪造(CSRF)是一种常见的网络安全攻击方式,它利用用户在已登录的情况下访问恶意网站,从而在不知情的情况下完成一些操作,如发送邮件、更改密码等。在本文中,我们将介绍如何使用PHP防止CSRF攻击。一、什么是CSRF攻击?CSRF攻击(Cross-SiteRequestForgery)又称为“跨站点请求伪造”,是一种利用用户已经登录过的网站,后台

    springBoot项目常用目录有哪些
    springBoot项目常用目录有哪些

    springBoot项目常用目录springBoot项目的目录结构及名规范介绍基于SpringBoot开发时的目录结构及命名规范,通过介绍能够为你解决,在实际项目中如何规划目录结构?如何命名目录更规范?各个目录分别代表什么含义?等三个问题。目录说明servicex//项目名|-admin-ui//管理服务前端代码(一般将UI和SERVICE放到一个工程中,便于管理)|-servicex-auth//模块1|-servicex-common//模块2|-servicex-gateway//模块3|-serv

    PHP实现安全编程:CSRF攻击与防御
    PHP实现安全编程:CSRF攻击与防御

    在互联网应用中,安全问题一直是一个重要的议题。其中,跨站请求伪造(Cross-SiteRequestForgery,CSRF)攻击是一个常见的漏洞,也是很容易被攻击者利用的漏洞。那么,如何在PHP开发中实现安全编程呢?本篇文章将着重介绍CSRF攻击和防御方案。一、什么是CSRF攻击?CSRF攻击,即跨站请求伪造,是一种利用受害者已登录的状态,在受害者毫不

    PHP中的CSRF攻击
    PHP中的CSRF攻击

    随着网络的不断发展,网页应用也越来越多,然而,安全问题也越来越引起人们的关注。CSRF(CrossSiteRequestForgery,即跨站请求伪造)攻击就是一种常见的网络安全问题。CSRF攻击是什么?所谓CSRF攻击,就是攻击者盗用了用户的身份,以用户的名义进行非法操作。通俗的讲,就是攻击者利用用户的登录态,在用户毫不知情的情况下,进行一些非法的操

    防范PHP中的跨站请求伪造(CSRF)攻击:网站安全策略
    防范PHP中的跨站请求伪造(CSRF)攻击:网站安全策略

    网站安全策略:PHP中的跨站请求伪造(CSRF)防范概述:随着互联网的发展,网站安全问题越来越受到重视。其中,跨站请求伪造(Cross-SiteRequestForgery,CSRF)攻击是一种常见的网络安全威胁。在本文中,我们将重点探讨在PHP中如何防范CSRF攻击,以保障网站和用户的安全。什么是CSRF攻击?CSRF攻击是一种利用用户已经在其他站点上

    绝地反击,反败为胜:PHP 跨站请求伪造(CSRF)防范的逆袭秘诀
    绝地反击,反败为胜:PHP 跨站请求伪造(CSRF)防范的逆袭秘诀

    使用CSRF令牌CSRF令牌是一种用于验证请求是否来自合法来源的随机字符串。您可以通过在用户的会话中存储CSRF令牌,并在每个请求中包含该令牌来实现CSRF防护。当服务器收到请求时,它会将请求中的令牌与存储在会话中的令牌进行比较。如果不匹配,则服务器会拒绝该请求。<?PHP//生成CSRF令牌$csrfToken=bin2hex(random_bytes(32));//将CSRF令牌存储在用户的会话中$_SESSioN["csrfToken"]=$csrfToken;//将CSRF令牌包含在每个请求

    洞察威胁,掌控全局:PHP 跨站请求伪造(CSRF)防范的艺术
    洞察威胁,掌控全局:PHP 跨站请求伪造(CSRF)防范的艺术

    1.CSRF攻击的原理CSRF攻击本质上是一种欺骗攻击。攻击者通过精心构造的恶意链接或表单诱骗受害者点击或访问,从而在受害者的浏览器中发送恶意请求。由于浏览器会自动携带受害者的身份验证信息(如Cookie),这些请求会以受害者的身份发出,从而绕过权限检查并执行恶意操作。2.如何防范CSRF攻击2.1使用表单令牌表单令牌是一种简单的CSRF防范措施。在每个表单中包含一个随机生成的令牌,并在服务器端验证该令牌。如果令牌不匹配,则拒绝请求。2.2使用同步令牌同步令牌与表单令牌类似,但它更加安全。同步令牌会在客户

    PHP 跨站请求伪造(CSRF)的防范策略
    PHP 跨站请求伪造(CSRF)的防范策略

    一、跨站请求伪造(CSRF)简介跨站请求伪造(CSRF)是一种常见的WEB安全漏洞,它允许攻击者在未经授权的情况下以受害者的身份执行恶意操作。CSRF攻击通常通过诱使用户点击恶意链接或打开恶意网站来发起,攻击者利用用户的信任,促使受害者在不知不觉中访问攻击者的服务器,并携带受害者的身份验证信息,向受害者的Web应用程序发送攻击者精心构造的请求。攻击者可以利用这些请求来执行各种恶意操作,例如修改或删除敏感数据、进行欺诈交易、发送垃圾邮件等。二、跨站请求伪造(CSRF)的危害CSRF攻击的危害是巨大的,它可能

    解决 CSRF 攻击:PHP 防范的完整指南
    解决 CSRF 攻击:PHP 防范的完整指南

    跨站请求伪造(CSRF)是一种网络安全攻击,用于欺骗用户在不知情的情况下执行操作。这种攻击使攻击者能够使用受害者的身份和权限来执行端点或操作。如何运作?CSRF攻击依赖于以下条件:受害者和攻击者都登录到同一个网站。受害者拥有攻击者想要执行的操作的权限。攻击者能够诱使受害者点击恶意链接或打开恶意网站。当这些条件满足时,攻击者可以创建恶意请求并诱使受害者执行。这是通过将恶意请求嵌入到合法网站中的表单或图像中来完成的。当受害者点击恶意链接或打开恶意网站时,请求将自动向网站发送。网站会认为请求来自受害者,并因此执

    查看更多
    精品专题 更多
    装机必备
    装机必备

    正软商城装机必备专区,精选办公、浏览器、安全防护、影音播放、压缩解压、设计创作和系统工具等电脑常用正版软件,帮助用户快速完成新电脑软件配置。

    Windows
    Windows

    正软商城Windows软件专区,汇集适用于Windows电脑的办公、设计、安全防护、影音播放、开发工具和系统优化软件,提供软件介绍、系统要求、正版授权及购买下载服务。

    PDF教程
    PDF教程

    正软商城PDF教程频道提供PDF编辑、转换、合并、拆分、压缩及格式处理方法,同时介绍常用PDF软件和工具的使用技巧。

    Mac软件 更多
    讯飞智作 网页版
    讯飞智作 网页版
    Windows/ macOS/ Linux

    讯飞智作是一款基于语音合成技术、虚拟人驱动技术与数字人形象声音构建能力的 AI 数字人音视频创作平台。

    火山引擎 网页版
    火山引擎 网页版
    Windows/ macOS/ Linux

    火山引擎是字节跳动旗下企业级云与AI服务平台。聚焦大模型核心能力,依托字节自研豆包多模态大模型,凭借火山方舟一站式平台,提供模型精调、推理部署、智能应用搭建等全链路服务,结合高性能AI算力,助力各行业快速落地大模型数字化与智能化应用。

    Aperty macOS版
    Aperty macOS版
    macOS

    Aperty 是 Skylum 推出的 AI 人像修图软件,支持自然肤质修饰、瑕疵处理、面部与身体调整、预设及批量同步。

    WINDOWS 更多
    讯飞智作 网页版
    讯飞智作 网页版
    Windows/ macOS/ Linux

    讯飞智作是一款基于语音合成技术、虚拟人驱动技术与数字人形象声音构建能力的 AI 数字人音视频创作平台。

    火山引擎 网页版
    火山引擎 网页版
    Windows/ macOS/ Linux

    火山引擎是字节跳动旗下企业级云与AI服务平台。聚焦大模型核心能力,依托字节自研豆包多模态大模型,凭借火山方舟一站式平台,提供模型精调、推理部署、智能应用搭建等全链路服务,结合高性能AI算力,助力各行业快速落地大模型数字化与智能化应用。

    PixTV 网页版
    PixTV 网页版
    Windows

    PixTV 是一款在浏览器中使用的 AI 视觉内容创作平台,提供图片、视频、音频、文字生成、AI 分镜、局部重绘、提示词反推和无限画布等工具,适合短剧、漫剧、广告及社交媒体内容制作。