springboot版本升級(jí)以及解決springsecurity漏洞的問題
背景
項(xiàng)目中要解決 Spring Security RegexRequestMatcher 認(rèn)證繞過漏洞(CVE-2022-22978) 漏洞問題,并且需要將項(xiàng)目的版本整體升級(jí)到boot版本2.1.7,升級(jí)改造過程非常的痛苦,一方面對(duì)整個(gè)框架的代碼不是很熟悉,另外對(duì)解決漏洞問題相對(duì)較少。
需求
解決Spring Security RegexRequestMatcher 認(rèn)證繞過漏洞(CVE-2022-22978) 漏洞,升級(jí)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 項(xiàng)目下 解決Spring Security RegexRequestMatcher 認(rèn)證繞過漏洞(CVE-2022-22978) 漏洞
升級(jí)boot版本2.1.7(和快速構(gòu)建保持一致)
注意下升級(jí)之后一些配置文件(例如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>
升級(jí)到2.x版本
<spring-cloud.version>Greenwich.SR2</spring-cloud.version> <spring-boot.version>2.1.7.RELEASE</spring-boot.version>
問題一:項(xiàng)目改造前是自定義的springboot依賴,現(xiàn)要求去掉原先的自定義封裝依賴
剛開始我是把原先自定義的springboot依賴的父依賴直接移到最外層,大概過程如下,導(dǎo)致出現(xiàn)一堆問題。
坑一:類不存在,或包不存在
項(xiàng)目中出現(xiàn)大量的類不存在,但是明明可以用鼠標(biāo)點(diǎn)擊進(jìn)去,此類問題經(jīng)常是idea,什么緩存,或者是pom依賴下載不全導(dǎo)致,然后就陷入了這個(gè)誤區(qū),一直以為是idea的問題。
先是清理 idea緩存、執(zhí)行mvn idea:idea命令等方式很多次還是無法解決。
然后分支代碼提交后,同事檢出也是同樣的問題,項(xiàng)目還是無法啟動(dòng),保錯(cuò)也是提示類不存在等。
此時(shí)我就懷疑可能不是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設(shè)置,最好調(diào)整成maven運(yùn)行(推薦)
否則會(huì)出現(xiàn)稀奇古怪的問題,比如上面的之前用parent依賴方式我本地可以跑(奇了怪),但是同事拉下拉卻跑不了,切換成eclipse也同樣項(xiàng)目跑不起來。
經(jīng)過一番折騰代碼是跑起來了總算不提示類不存等問題。
代碼兼容問題
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跨版本升級(jí)后,需要把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
- 改造前邏輯
@Override public ValidateCode get(ServletWebRequest request, ValidateCodeType validateCodeType) { Object object = redisTemplate.opsForValue().get(buildKey(request, validateCodeType)); if (object == null) { return null; } return (ValidateCode)object ; }
- 改造后
@Override public 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); }
問題解決!?。?!
問題二:升級(jí)后通過feign調(diào)用認(rèn)證服務(wù)接口/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在實(shí)現(xiàn)類中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在實(shí)現(xiàn)類中改方法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")); } } }
邏輯變化了
使用了自定義的密碼加密類
密碼加密方式發(fā)現(xiàn)不一樣了,因此按照原先代碼邏輯獲取到的前后密碼其實(shí)是一樣的,但是升級(jí)后GisqPasswordEncoder起了作用,因此在比較時(shí)應(yīng)該時(shí)加密后的匹配
因此改成這樣
問題三:feign調(diào)用token校驗(yàn)接口,在項(xiàng)目中未搜索到
后來打斷點(diǎn)才發(fā)現(xiàn)竟然后spring-security-oaruth2包內(nèi)部類CheckTokenEndpoint中的接口,無語(yǔ),我還以為是自己定義的呢找了半天未找打?。。。?!
jar包依賴沖突問題
方式一:選擇依賴的模塊,鼠標(biāo)右鍵,選擇show dependency
如果有沖突會(huì)出現(xiàn)報(bào)紅!??!
方式二:安裝一個(gè)maven-helper插件
如果有沖突會(huì)自動(dòng)顯示,然后去排處即可
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Java實(shí)現(xiàn)并發(fā)執(zhí)行定時(shí)任務(wù)并手動(dòng)控制開始結(jié)束
這篇文章主要介紹了Java實(shí)現(xiàn)并發(fā)執(zhí)行定時(shí)任務(wù)并手動(dòng)控制開始結(jié)束,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-05-05基于java socket實(shí)現(xiàn) 聊天小程序
這篇文章主要介紹了基于java socket實(shí)現(xiàn) 聊天小程序,代碼分為服務(wù)器和客戶端,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-12-12Spring Boot集成Shiro實(shí)現(xiàn)動(dòng)態(tài)加載權(quán)限的完整步驟
這篇文章主要給大家介紹了關(guān)于Spring Boot集成Shiro實(shí)現(xiàn)動(dòng)態(tài)加載權(quán)限的完整步驟,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用Spring Boot具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧2019-09-09導(dǎo)致MyEclipse內(nèi)存不足的原因分析及解決辦法
這篇文章主要介紹了導(dǎo)致MyEclipse內(nèi)存不足的原因分析及解決辦法的相關(guān)資料,需要的朋友可以參考下2016-01-01Java編程實(shí)現(xiàn)二項(xiàng)分布的采樣或抽樣實(shí)例代碼
這篇文章主要介紹了Java編程實(shí)現(xiàn)二項(xiàng)分布的采樣或抽樣實(shí)例代碼,小編覺得還是挺不錯(cuò)的,具有一定借鑒價(jià)值,需要的朋友可以參考下2018-01-01基于SpringBoot和Vue實(shí)現(xiàn)分片上傳系統(tǒng)
最近想做一個(gè)關(guān)于文件上傳的個(gè)人小網(wǎng)盤,一開始嘗試使用了OSS的方案,但是該方案對(duì)于大文件來說并不友好,所以開始嘗試分片上傳方案的探索,接下來小編給大家詳細(xì)的介紹一下如何基于SpringBoot和Vue實(shí)現(xiàn)分片上傳系統(tǒng),需要的朋友可以參考下2023-12-12