【安全漏洞】SpringBoot + SpringSecurity CORS跨域资源共享配置

本文主要是介绍【安全漏洞】SpringBoot + SpringSecurity CORS跨域资源共享配置,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

SpringBoot CORS跨域资源共享


文章目录

  • SpringBoot CORS跨域资源共享
  • 前言
  • 一、什么是CORS?
  • 二、配置CORS方法
    • 1.nginx中配置跨域资源访问策略
    • 2.springSecurity 过滤器链中配置跨域资源访问策略
    • 3.springBoot 中配置跨域资源访问策略
  • 总结


前言

一个健壮的系统上线时,以及后续验收过程中,通常都会做系统安全测评,这是信息系统正式上线安全运行的重要环节。我们大概率会遇到一个叫:跨域资源共享漏洞的漏洞要求整改,具体描述大概是:“经测试发现服务器存在不安全的CORS配置,存在恶意跨域请求和内部信息泄露的风险。”今天我们就来了解一下这个CROS漏洞,并记录一下在整合了springSecurity这一套安全框架下的springboot系统中如何在后端过滤器中通过正确注册WebMvcConfigurer bean来配置CORS的全局设置,实现对非白名单访问源的拦截。


一、什么是CORS?

CORS,全称是“跨源资源共享”(Cross-Origin Resource Sharing),是一种Web应用程序的安全机制,用于控制不同源的资源之间的交互。
在Web应用程序中,CORS定义了一种机制,通过该机制,浏览器能够限制哪些外部网页可以访问来自不同源的资源。源由协议、域名和端口组成。当一个网页请求另一个网页上的资源时,浏览器会检查请求是否符合CORS规范,以确定是否允许该请求。
CORS的工作原理是:当浏览器发送一个跨域请求时,它会附加一些额外的头部信息到请求中,这些头部信息包含了关于请求的来源和目的的信息。服务器可以检查这些头部信息并决定是否允许该请求。如果服务器允许请求,它会返回一个响应,其中包含一个名为“Access-Control-Allow-Origin”的头部信息,该信息指定了哪些源可以访问该资源。浏览器会检查返回的“Access-Control-Allow-Origin”头部信息,以确定是否允许该跨域请求。通过使用CORS,开发人员可以控制哪些外部网页可以访问他们的资源,从而提高应用程序的安全性。

二、配置CORS方法

1.nginx中配置跨域资源访问策略

nginx中配置跨域资源访问策略,在之前的博客中已经写过具体配置方法了,需要的朋友直接移步以下博客链接查看:
https://blog.csdn.net/weixin_42925623/article/details/134548502

2.springSecurity 过滤器链中配置跨域资源访问策略

在Spring框架中,我们可以在引入Spring Security依赖后,对Security的HttpSecurity进行设置,来开启CORS(跨域/源资源共享),同时能指定只被部分域/源、部分方法、部分头部信息访问资源。
(1)SecurityConfig中过滤器链的配置示例:

@Bean@Order(3)public SecurityFilterChain defaultFilterChain(HttpSecurity http, IGuavaCacheService guavaCacheService, IUsersService usersService, ICaptchaApi captchaApi, JwtEncoder jwtEncoder, JwtDecoder jwtDecoder) throws Exception {http.authorizeHttpRequests(requestMatcherRegistryCustomizer).csrf().disable()//.cors().disable()//关闭cros配置//.cors(withDefaults())//默认cros配置允许所有来源访问.cors().and()//开启cros配置.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and().authenticationProvider(jwtAuthenticationProvider(jwtDecoder))//在UsernamePasswordAuthenticationFilter前边添加自定义用户认证处理器.addFilterBefore(new CustomUserAuthenticationFilter(authProperties.getLoginProcessingPath(), guavaCacheService.userLockService()), UsernamePasswordAuthenticationFilter.class).addFilterBefore(new CaptAuthenticationFilter(captchaApi, authProperties.getLoginProcessingPath()), CustomUserAuthenticationFilter.class)//主要用于控制UsernamePasswordAuthenticationFilter行为.formLogin()//login静态页面地址,需要和前端静态页面保持一致.loginPage(authProperties.getFrontLoginUrl()).loginProcessingUrl(authProperties.getLoginProcessingPath()).permitAll().successHandler(new ResultAuthenticationSuccessHandler(usersService,new JwtUtils(jwtEncoder), authProperties.getJwtLifetime(), authProperties.getIssuer(), macService)).failureHandler(new ResultAuthenticationFailedHandler(guavaCacheService.userLockService())).and()//处理业务层的认证异常和权限问题,主要用于控制ExceptionTranslationFilter行为.exceptionHandling().authenticationEntryPoint(new RedirectAuthenticationEntryPoint(authProperties.getFrontLoginUrl())).and()//jwt认证.oauth2ResourceServer().authenticationEntryPoint(new BearerTokenAuthenticationEntryPoint()).jwt().decoder(jwtDecoder);//让jwt过滤器共用认证器DefaultSecurityFilterChain build = http.build();return build;}

重点在于cors 这一块语法配置
//关闭cros配置
.cors().disable()
//使用默认cros配置允许所有来源访问
.cors(withDefaults())
//开启cros配置,配置规则以自定义注册的cros配置为准
.cors().and()

(2)使用addCorsMappings方法来配置CORS
在Spring框架中,我们可以使用addCorsMappings(CorsRegistry registry)方法来配置CORS。
这个方法接收一个CorsRegistry对象,我们可以在这个对象中添加我们的路径和对应的CORS配置。
以下是addCorsMappings方法来配置CORS示例代码:

package com.dg.dp.user.auth.server.config;import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;/*** @Author:* @Date:2024/9/4 18:16* CORS跨域资源共享允许访问源*/
@Configuration
public class WebConfig implements WebMvcConfigurer {@Value("${allow.origin}")String allowOrigin;@Overridepublic void addCorsMappings(CorsRegistry registry) {String[] allowDomain = allowOrigin.split(",");// 允许所有路径的跨域请求registry.addMapping("/**")// 配置允许的访问源.allowedOrigins(allowDomain)// 允许的请求方法.allowedMethods("GET", "POST", "PUT", "DELETE", "HEAD", "OPTIONS")// 允许的请求头.allowedHeaders("*")// 是否允许携带凭证.allowCredentials(true);}
}

其中,allowOrigin为yml配置文件中配置的访问源白名单:

#CORS跨域资源共享允许访问源白名单,多个访问源用逗号分隔
allow:origin: http://example.com,http://127.1.2.3:28080

.allowedOrigins()配置允许访问源可以为多个,可以放到字符串数组塞进去;
.addMapping(“/**”)表示允许所有路径的跨域请求;
WebMvcConfigurer 需要pom.xml文件引入依赖:

        <dependency><groupId>org.springframework</groupId><artifactId>spring-webmvc</artifactId></dependency>

(3)postman测试配置后的效果
同域下的请求(即Origin配置域名与接口路径前缀域名相同),不存在跨域问题,所以直接可以访问:
在这里插入图片描述
注意,如果请求的地址前缀是ip:port,那需要请求头配置的Origin值的ip:port跟接口请求路径中的ip端口一模一样,如果不一样会被认为是跨域请求,这时候如果代码的allowedOrigins配置白名单也没有该地址,就会被当做异常请求被拦截。
请求头携带的Origin中ip和接口中ip一致,端口不一致会被拦截:
在这里插入图片描述
请求头携带的Origin中配置的域名在代码allowedOrigins配置白名单中,会被认为是可信访问源而被放行:
在这里插入图片描述
在这里插入图片描述

请求头携带的Origin中配置的域名不在代码allowedOrigins配置白名单中,也不与接口前缀域名相同时,会被认为是非法访问源而被拦截掉:
在这里插入图片描述

3.springBoot 中配置跨域资源访问策略

如果springBoot项目没有引入springSecurity框架,这个时候,以上使用addCorsMappings(CorsRegistry registry)方法,或者接下来要讲的,创建一个 CorsFilter 的 Bean 并将其添加到 Spring 容器中,都可以实现cors配置。
addCorsMappings方法来配置CORS示例代码:

package com.dg.dp.user.auth.server.config;import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;/*** @Author:* @Date:2024/9/4 18:16* CORS跨域资源共享允许访问源*/
@Configuration
public class WebConfig implements WebMvcConfigurer {@Value("${allow.origin}")String allowOrigin;@Overridepublic void addCorsMappings(CorsRegistry registry) {String[] allowDomain = allowOrigin.split(",");// 允许所有路径的跨域请求registry.addMapping("/**")// 配置允许的访问源.allowedOrigins(allowDomain)// 允许的请求方法.allowedMethods("GET", "POST", "PUT", "DELETE", "HEAD", "OPTIONS")// 允许的请求头.allowedHeaders("*")// 是否允许携带凭证.allowCredentials(true);}
}

创建一个配置类CorsConfig,并CorsFilter corsFilter()方法作为bean注入到spring 容器,代码示例如下:

package com.digitalgd.sasacdataboard.config;import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;/*** @Author:* @Date:2024/9/5 14:55*/@Configuration
public class CorsConfig {@Beanpublic CorsFilter corsFilter() {CorsConfiguration corsConfiguration = new CorsConfiguration();corsConfiguration.addAllowedOrigin("http://example.com");corsConfiguration.addAllowedMethod("*");corsConfiguration.addAllowedHeader("*");corsConfiguration.setAllowCredentials(true);UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();source.registerCorsConfiguration("/**", corsConfiguration);return new CorsFilter(source);}}

总结

以上就是CROS跨域资源共享安全漏洞修复方法的全部内容,欢迎评论区交流学习!

这篇关于【安全漏洞】SpringBoot + SpringSecurity CORS跨域资源共享配置的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1139659

相关文章

使用Java将各种数据写入Excel表格的操作示例

《使用Java将各种数据写入Excel表格的操作示例》在数据处理与管理领域,Excel凭借其强大的功能和广泛的应用,成为了数据存储与展示的重要工具,在Java开发过程中,常常需要将不同类型的数据,本文... 目录前言安装免费Java库1. 写入文本、或数值到 Excel单元格2. 写入数组到 Excel表格

Java并发编程之如何优雅关闭钩子Shutdown Hook

《Java并发编程之如何优雅关闭钩子ShutdownHook》这篇文章主要为大家详细介绍了Java如何实现优雅关闭钩子ShutdownHook,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起... 目录关闭钩子简介关闭钩子应用场景数据库连接实战演示使用关闭钩子的注意事项开源框架中的关闭钩子机制1.

Maven中引入 springboot 相关依赖的方式(最新推荐)

《Maven中引入springboot相关依赖的方式(最新推荐)》:本文主要介绍Maven中引入springboot相关依赖的方式(最新推荐),本文给大家介绍的非常详细,对大家的学习或工作具有... 目录Maven中引入 springboot 相关依赖的方式1. 不使用版本管理(不推荐)2、使用版本管理(推

Java 中的 @SneakyThrows 注解使用方法(简化异常处理的利与弊)

《Java中的@SneakyThrows注解使用方法(简化异常处理的利与弊)》为了简化异常处理,Lombok提供了一个强大的注解@SneakyThrows,本文将详细介绍@SneakyThro... 目录1. @SneakyThrows 简介 1.1 什么是 Lombok?2. @SneakyThrows

在 Spring Boot 中实现异常处理最佳实践

《在SpringBoot中实现异常处理最佳实践》本文介绍如何在SpringBoot中实现异常处理,涵盖核心概念、实现方法、与先前查询的集成、性能分析、常见问题和最佳实践,感兴趣的朋友一起看看吧... 目录一、Spring Boot 异常处理的背景与核心概念1.1 为什么需要异常处理?1.2 Spring B

SpringBoot3.4配置校验新特性的用法详解

《SpringBoot3.4配置校验新特性的用法详解》SpringBoot3.4对配置校验支持进行了全面升级,这篇文章为大家详细介绍了一下它们的具体使用,文中的示例代码讲解详细,感兴趣的小伙伴可以参考... 目录基本用法示例定义配置类配置 application.yml注入使用嵌套对象与集合元素深度校验开发

如何在 Spring Boot 中实现 FreeMarker 模板

《如何在SpringBoot中实现FreeMarker模板》FreeMarker是一种功能强大、轻量级的模板引擎,用于在Java应用中生成动态文本输出(如HTML、XML、邮件内容等),本文... 目录什么是 FreeMarker 模板?在 Spring Boot 中实现 FreeMarker 模板1. 环

SpringMVC 通过ajax 前后端数据交互的实现方法

《SpringMVC通过ajax前后端数据交互的实现方法》:本文主要介绍SpringMVC通过ajax前后端数据交互的实现方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价... 在前端的开发过程中,经常在html页面通过AJAX进行前后端数据的交互,SpringMVC的controll

Java中的工具类命名方法

《Java中的工具类命名方法》:本文主要介绍Java中的工具类究竟如何命名,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录Java中的工具类究竟如何命名?先来几个例子几种命名方式的比较到底如何命名 ?总结Java中的工具类究竟如何命名?先来几个例子JD

Java Stream流使用案例深入详解

《JavaStream流使用案例深入详解》:本文主要介绍JavaStream流使用案例详解,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录前言1. Lambda1.1 语法1.2 没参数只有一条语句或者多条语句1.3 一个参数只有一条语句或者多