本文主要是介绍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漏洞问题的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!