springboot版本升级,及解决springsecurity漏洞问题

本文主要是介绍springboot版本升级,及解决springsecurity漏洞问题,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

背景:

项目中要解决 Spring Security RegexRequestMatcher 认证绕过漏洞(CVE-2022-22978) 漏洞问题,并且需要将项目的版本整体升级到boot版本2.1.7,升级改造过程非常的痛苦,一方面对整个框架的代码不是很熟悉,另外对解决漏洞问题相对较少。

需求:

 解决Spring Security RegexRequestMatcher 认证绕过漏洞(CVE-2022-22978) 漏洞,升级boot版本2.1.7

改造前父pom如下(部分依赖省略):

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.gisquest.realestate</groupId><artifactId>gisqrealestate-unityplatform-core</artifactId><version>2.2.1.RELEASE</version><modules><module>unityplatform-security</module><module>unityplatform-microauth</module><module>unityplatform-apigateway</module><module>unityplatform-servicediscovery</module><module>unityplatform-microappadmin</module><module>unityplatform-apigateway-core</module><module>unityplatform-apigateway-app</module><module>unityplatform-microauth-app</module><module>unityplatform-core-comm</module></modules><packaging>pom</packaging><properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><spring-boot-admin.version>1.5.6</spring-boot-admin.version><jjwt.version>0.7.0</jjwt.version><commons-lang3.version>3.3.2</commons-lang3.version><swagger2.version>2.7.0</swagger2.version><apollo-client.version>1.0.0</apollo-client.version><jackson.version>2.10.2</jackson.version><!--micro version--><micro-apigateway.version>2.2.1.RELEASE</micro-apigateway.version><micro-auth.version>2.2.1.RELEASE</micro-auth.version><micro-comm.version>2.2.1.RELEASE</micro-comm.version><micro-apigateway.img.version>2.2.RELEASE</micro-apigateway.img.version><micro-auth.img.version>2.2.RELEASE</micro-auth.img.version><micro.img.version>2.2.RELEASE</micro.img.version><com.hanweb.SecurityUtil.version>1.0</com.hanweb.SecurityUtil.version><!--XStream --><xstream.version>1.4.20</xstream.version><spring.version>5.3.20</spring.version><spring-security.version>5.5.8</spring-security.version></properties><dependencyManagement><dependencies><dependency><groupId>io.spring.platform</groupId><artifactId>platform-bom</artifactId><version>Brussels-SR7</version><type>pom</type><scope>import</scope></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-dependencies</artifactId><version>Edgware.SR2</version><type>pom</type><scope>import</scope></dependency></dependencies></dependencyManagement>
</project>

漏洞解决方案

gisqrealestate-unityplatform-core 项目下 解决Spring Security RegexRequestMatcher 认证绕过漏洞(CVE-2022-22978) 漏洞,升级boot版本2.1.7(和快速构建保持一致),注意下升级之后一些配置文件(例如redis,文件限制大小等) 和 代码 不兼容问题

漏洞影响版本

5.5.0 <= Spring Security < 5.5.7

5.6.0 <= Spring Security < 5.6.4

版本改造问题:

改造前 版本 

<spring-cloud.version>Edgware.SR2</spring-cloud.version> 
<spring-boot.version>1.5.10.RELEASE </spring-boot.version>
升级到2.x版本
<spring-cloud.version>Greenwich.SR2</spring-cloud.version>
<spring-boot.version>2.1.7.RELEASE</spring-boot.version>

问题一:项目改造前是自定义的springboot依赖,现要求去掉原先的自定义封装依赖

刚开始我是把原先自定义的springboot依赖的父依赖直接移到最外层,大概过程如下,导致出现一堆问题。

坑一:类不存在,或包不存在

项目中出现大量的类不存在,但是明明可以用鼠标点击进去,此类问题经常是idea,什么缓存,或者是pom依赖下载不全导致,然后就陷入了这个误区,一直以为是idea的问题。

先是清理 idea缓存、执行mvn idea:idea命令等方式很多次还是无法解决。 

然后分支代码提交后,同事检出也是同样的问题,项目还是无法启动,保错也是提示类不存在等。

此时我就怀疑可能不是idea的问题了。

后面就换了一种方式

<parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>1.5.10.RELEASE</version><relativePath />
</parent>

改成

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-dependencies</artifactId><version>${spring-boot.version}</version><type>pom</type><scope>import</scope>
</dependency>

 妈的改成这样后终于正常了,不在提示类不存在,包不存在等问题了。

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><groupId>com.gisquest.realestate</groupId><artifactId>gisqrealestate-unityplatform-core</artifactId><version>2.2.1.RELEASE</version><modelVersion>4.0.0</modelVersion><packaging>pom</packaging><modules><module>unityplatform-security</module><module>unityplatform-microauth</module><module>unityplatform-apigateway</module><module>unityplatform-servicediscovery</module><module>unityplatform-microappadmin</module><module>unityplatform-apigateway-core</module><module>unityplatform-apigateway-app</module><module>unityplatform-microauth-app</module><module>unityplatform-core-comm</module></modules><properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><spring-boot-admin.version>1.5.6</spring-boot-admin.version><jjwt.version>0.7.0</jjwt.version><commons-lang3.version>3.3.2</commons-lang3.version><swagger2.version>2.7.0</swagger2.version><apollo-client.version>1.0.0</apollo-client.version><jackson.version>2.10.2</jackson.version><!--micro version--><micro-apigateway.version>2.2.1.RELEASE</micro-apigateway.version><micro-auth.version>2.2.1.RELEASE</micro-auth.version><micro-comm.version>2.2.1.RELEASE</micro-comm.version><micro-apigateway.img.version>2.2.RELEASE</micro-apigateway.img.version><micro-auth.img.version>2.2.RELEASE</micro-auth.img.version><micro.img.version>2.2.RELEASE</micro.img.version><com.hanweb.SecurityUtil.version>1.0</com.hanweb.SecurityUtil.version><!--XStream --><xstream.version>1.4.19</xstream.version><spring-cloud.version>Greenwich.SR2</spring-cloud.version><spring-boot.version>2.1.7.RELEASE</spring-boot.version><eureka.version>2.1.0.RELEASE</eureka.version><openfeign.version>2.0.0.RELEASE</openfeign.version><zuul.version>2.1.2.RELEASE</zuul.version><commons-lang.version>2.6</commons-lang.version><commons-collections.version>3.2.2</commons-collections.version><commons-beanutils.version>1.9.3</commons-beanutils.version></properties><dependencyManagement><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-dependencies</artifactId><version>${spring-boot.version}</version><type>pom</type><scope>import</scope></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-dependencies</artifactId><version>${spring-cloud.version}</version><type>pom</type><scope>import</scope></dependency></project>

坑二:idea中maven设置,最好调整成maven运行(推荐)

否则会出现稀奇古怪的问题,比如上面的之前用parent依赖方式我本地可以跑(奇了怪),但是同事拉下拉却跑不了,切换成eclipse也同样项目跑不起来。

经过一番折腾代码是跑起来了总算不提示类不存等问题。

代码兼容问题

org.springframework.data.redis.serializer.SerializationException: Cannot deserialize

org.springframework.data.redis.serializer.SerializationException: Cannot deserialize; nested exception is org.springframework.core.serializer.support.SerializationFailedException: Failed to deserialize payload. Is the byte array a result of corresponding serialization for DefaultDeserializer?; nested exception is java.io.InvalidClassException: org.springframework.security.core.authority.SimpleGrantedAuthority; local class incompatible: stream classdesc serialVersionUID = 420, local class serialVersionUID = 510
    at org.springframework.data.redis.serializer.JdkSerializationRedisSerializer.deserialize(JdkSerializationRedisSerializer.java:84) ~[spring-data-redis-2.1.10.RELEASE.jar!/:2.1.10.RELEASE]

解决方法:

redis跨版本升级后,需要把redis缓存清理一下

问题二:alibaba.fastjson.JSONObject cannot be cast to xx

java.lang.ClassCastException: com.alibaba.fastjson.JSONObject cannot be cast to com.gisquest.realestate.security.validate.code.ValidateCode

改造前逻辑

@Overridepublic ValidateCode get(ServletWebRequest request, ValidateCodeType validateCodeType) {Object object = redisTemplate.opsForValue().get(buildKey(request, validateCodeType));if (object == null) {return null;}return (ValidateCode)object ;}

改造后

@Overridepublic ValidateCode get(ServletWebRequest request, ValidateCodeType validateCodeType) {Object object = redisTemplate.opsForValue().get(buildKey(request, validateCodeType));if (object == null) {return null;}String josn =JSON.toJSONString(object);return JSONObject.parseObject(josn,ValidateCode.class);}

问题解决!!!!

问题三:   升级后通过feign调用认证服务接口/oauth/check_token接口提示如下 Illegal hexadecimal character - at index 8
 

org.apache.commons.codec.DecoderException: Illegal hexadecimal character - at index 8
    at org.apache.commons.codec.binary.Hex.toDigit(Hex.java:286)
    at org.apache.commons.codec.binary.Hex.decodeHex(Hex.java:106)
    at com.gisquest.realestate.utils.Encodes.decodeHex(Encodes.java:41)

原因版本问题

改造前spring-security-core-4.2.4.RELEASE

在AbstractUserDetailsAuthenticationProvider在实现类中additionalAuthenticationChecks方法逻辑如下

	protected void additionalAuthenticationChecks(UserDetails userDetails,UsernamePasswordAuthenticationToken authentication)throws AuthenticationException {Object salt = null;if (this.saltSource != null) {salt = this.saltSource.getSalt(userDetails);}if (authentication.getCredentials() == null) {logger.debug("Authentication failed: no credentials provided");throw new BadCredentialsException(messages.getMessage("AbstractUserDetailsAuthenticationProvider.badCredentials","Bad credentials"));}String presentedPassword = authentication.getCredentials().toString();if (!passwordEncoder.isPasswordValid(userDetails.getPassword(),presentedPassword, salt)) {logger.debug("Authentication failed: password does not match stored value");throw new BadCredentialsException(messages.getMessage("AbstractUserDetailsAuthenticationProvider.badCredentials","Bad credentials"));}}

改造后

spring-security-core-5.1.6.RELEASE版本中AbstractUserDetailsAuthenticationProvider在实现类中改方法additionalAuthenticationChecks

   protected void additionalAuthenticationChecks(UserDetails userDetails, UsernamePasswordAuthenticationToken authentication) throws AuthenticationException {if (authentication.getCredentials() == null) {this.logger.debug("Authentication failed: no credentials provided");throw new BadCredentialsException(this.messages.getMessage("AbstractUserDetailsAuthenticationProvider.badCredentials", "Bad credentials"));} else {String presentedPassword = authentication.getCredentials().toString();if (!this.passwordEncoder.matches(presentedPassword, userDetails.getPassword())) {this.logger.debug("Authentication failed: password does not match stored value");throw new BadCredentialsException(this.messages.getMessage("AbstractUserDetailsAuthenticationProvider.badCredentials", "Bad credentials"));}}}

   逻辑变化了

使用了自定义的密码加密类

 密码加密方式发现不一样了,因此按照原先代码逻辑获取到的前后密码其实是一样的,但是升级后GisqPasswordEncoder起了作用,因此在比较时应该时加密后的匹配

因此改成这样

问题四:feign调用token校验接口,在项目中未搜索到,

后来打断点才发现竟然后spring-security-oaruth2包内部类CheckTokenEndpoint中的接口,无语,我还以为是自己定义的呢找了半天未找打!!!!!

jar包依赖冲突问题:

方式一:选择依赖的模块,鼠标右键,选择show dependency

,如果有冲突会出现报红!!!

方式二:安装一个maven-helper插件

如果有冲突会自动显示,然后去排处即可

这篇关于springboot版本升级,及解决springsecurity漏洞问题的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

JVM 的类初始化机制

前言 当你在 Java 程序中new对象时,有没有考虑过 JVM 是如何把静态的字节码(byte code)转化为运行时对象的呢,这个问题看似简单,但清楚的同学相信也不会太多,这篇文章首先介绍 JVM 类初始化的机制,然后给出几个易出错的实例来分析,帮助大家更好理解这个知识点。 JVM 将字节码转化为运行时对象分为三个阶段,分别是:loading 、Linking、initialization

Spring Security 基于表达式的权限控制

前言 spring security 3.0已经可以使用spring el表达式来控制授权,允许在表达式中使用复杂的布尔逻辑来控制访问的权限。 常见的表达式 Spring Security可用表达式对象的基类是SecurityExpressionRoot。 表达式描述hasRole([role])用户拥有制定的角色时返回true (Spring security默认会带有ROLE_前缀),去

浅析Spring Security认证过程

类图 为了方便理解Spring Security认证流程,特意画了如下的类图,包含相关的核心认证类 概述 核心验证器 AuthenticationManager 该对象提供了认证方法的入口,接收一个Authentiaton对象作为参数; public interface AuthenticationManager {Authentication authenticate(Authenti

Spring Security--Architecture Overview

1 核心组件 这一节主要介绍一些在Spring Security中常见且核心的Java类,它们之间的依赖,构建起了整个框架。想要理解整个架构,最起码得对这些类眼熟。 1.1 SecurityContextHolder SecurityContextHolder用于存储安全上下文(security context)的信息。当前操作的用户是谁,该用户是否已经被认证,他拥有哪些角色权限…这些都被保

Spring Security基于数据库验证流程详解

Spring Security 校验流程图 相关解释说明(认真看哦) AbstractAuthenticationProcessingFilter 抽象类 /*** 调用 #requiresAuthentication(HttpServletRequest, HttpServletResponse) 决定是否需要进行验证操作。* 如果需要验证,则会调用 #attemptAuthentica

Spring Security 从入门到进阶系列教程

Spring Security 入门系列 《保护 Web 应用的安全》 《Spring-Security-入门(一):登录与退出》 《Spring-Security-入门(二):基于数据库验证》 《Spring-Security-入门(三):密码加密》 《Spring-Security-入门(四):自定义-Filter》 《Spring-Security-入门(五):在 Sprin

Java架构师知识体认识

源码分析 常用设计模式 Proxy代理模式Factory工厂模式Singleton单例模式Delegate委派模式Strategy策略模式Prototype原型模式Template模板模式 Spring5 beans 接口实例化代理Bean操作 Context Ioc容器设计原理及高级特性Aop设计原理Factorybean与Beanfactory Transaction 声明式事物

Java进阶13讲__第12讲_1/2

多线程、线程池 1.  线程概念 1.1  什么是线程 1.2  线程的好处 2.   创建线程的三种方式 注意事项 2.1  继承Thread类 2.1.1 认识  2.1.2  编码实现  package cn.hdc.oop10.Thread;import org.slf4j.Logger;import org.slf4j.LoggerFactory

好题——hdu2522(小数问题:求1/n的第一个循环节)

好喜欢这题,第一次做小数问题,一开始真心没思路,然后参考了网上的一些资料。 知识点***********************************无限不循环小数即无理数,不能写作两整数之比*****************************(一开始没想到,小学没学好) 此题1/n肯定是一个有限循环小数,了解这些后就能做此题了。 按照除法的机制,用一个函数表示出来就可以了,代码如下

hdu1043(八数码问题,广搜 + hash(实现状态压缩) )

利用康拓展开将一个排列映射成一个自然数,然后就变成了普通的广搜题。 #include<iostream>#include<algorithm>#include<string>#include<stack>#include<queue>#include<map>#include<stdio.h>#include<stdlib.h>#include<ctype.h>#inclu