优秀的编程知识分享平台

网站首页 > 技术文章 正文

尝试将springboot2.7.11升级到3.2.3

nanyue 2025-02-28 16:51:46 技术文章 10 ℃

一、背景

spring boot 修复 Spring Framework URL解析不当漏洞(CVE-2024-22243)

1、漏洞描述

当应用程序使用UriComponentsBuilder来解析外部提供的URL(如通过查询参数)并对解析的URL的主机执行验证检查时可能容易受到Open重定向攻击和SSRF攻击,导致网络钓鱼和内部网络探测等。

2、受影响产品或系统

6.1.0 <= Spring Framework <= 6.1.3
6.0.0 <= Spring Framework <= 6.0.16
5.3.0 <= Spring Framework <= 5.3.31

3、官方建议修复方案

Spring Framework 版本6.1.x 用户:升级到 6.1.4
Spring Framework 版本6.0.x 用户:升级到 6.0.17
Spring Framework 版本5.3.x 用户:升级到 5.3.32
springboot升级到3.1.9或者3.2.3
其它已经不受官方支持的版本(5.1.x,5.2.x)同样受到影响,更新到受官方支持的安全版本。

因为我们的系统是2.7.11,所以尝试升级到最新的版本3.2.3。

一、升级过程

1、复制项目

由于2到3改动太大,升级不一定成功,所以这里复制一份项目,复制完后记得修改下pom.xml的项目名称
2、修改springboot的版本依赖
这里将2.7.11改到3.2.3

 
      org.springframework.boot
      spring-boot-starter-parent
  
       3.2.3
  

重新编译

3、启动测试

不要管报错,直接启动测试,发现jdk版本不对

Exception in thread "main" java.lang.UnsupportedClassVersionError: org/springframework/boot/SpringApplication has been compiled by a more recent version of the Java Runtime (class file version 61.0), this version of the Java Runtime only recognizes class file versions up to 52.0
    at java.lang.ClassLoader.defineClass1(Native Method)

1、2019年1月15日发布的Oracle JDK 8u201和8u202是最后一个免费版本,后续的都是收费的
2、springboot3.x后最少都要jdk17,所以这里只能用开源的openjdk17或者RedHatOpenJDK17

4、替换servlet的相关import

springboot3.x后用的是jakarta,所以也没上所有涉及这些引入的地方全部都要改动

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

改为

import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;

包括但不限于上面三个,这边几乎在所有Controller和service的页面都有修改,所以就没个页面都打开替换了一下,最后再看,但是一开始会发现没有这些依赖,这里需要再pom.xml引入

        
            jakarta.persistence
            jakarta.persistence-api
            3.1.0
        
        
            jakarta.servlet
            jakarta.servlet-api
            6.0.0
        

eclipse并不会立即提示那些类没有引入,可能是我eclipse版本的原因,只能一个个改,有时候还会没有任何反应,启动也启动不了,这时只能重启

5、org/yaml/snakeyaml/inspector/TagInspector的错误

这里上面一步骤后还会有写类报错,这里暂时不处理先,直接先启动发现

17:15:09.565 [restartedMain] ERROR org.springframework.boot.SpringApplication - Application run failed
java.lang.NoClassDefFoundError: org/yaml/snakeyaml/inspector/TagInspector
Caused by: java.lang.IllegalStateException: java.lang.NoClassDefFoundError: org/yaml/snakeyaml/inspector/TagInspector
    at org.springframework.boot.SpringApplication.handleRunFailure(SpringApplication.java:825)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:344)
    at com.gdpost.activity.mgr.AppActivityMGR.main(AppActivityMGR.java:23)
    ... 5 more

这个需要再pom.xml引入


            org.yaml
            snakeyaml
            2.2
        

6、日志冲突

启动后会报一连串日志冲突错误

The following method did not exist:

    'void org.apache.logging.log4j.util.PropertiesUtil.addPropertySource(org.apache.logging.log4j.util.PropertySource)'

The calling method's class, org.springframework.boot.logging.log4j2.Log4J2LoggingSystem, was loaded from the following location:

    jar:file:/D:/Software/repository/org/springframework/boot/spring-boot/3.2.3/spring-boot-3.2.3.jar!/org/springframework/boot/logging/log4j2/Log4J2LoggingSystem.class

The called method's class, org.apache.logging.log4j.util.PropertiesUtil, is available from the following locations:

我这里是把相关引入的日志注释

   

具体每个系统具体分析,这里还把其它应用日志的版本也去掉才行,不然好像还报如下错误

ERROR StatusLogger Unable to create Lookup for ctx
 java.lang.NoSuchMethodError: 'java.lang.ClassLoader[] org.apache.logging.log4j.util.LoaderUtil.getClassLoaders()'

7、 Invalid value type for attribute ‘factoryBeanObjectType’:

TRACE StatusConsoleListener AsyncLoggerConfig[org.springframework.context.annotation.ConfigurationClassPostProcessor] stopping...
[2024-03-07 17:22:13,114]-[ERROR]-[restartedMain]-[org.springframework.boot.SpringApplication]-[]-Application run failed
java.lang.IllegalArgumentException: Invalid value type for attribute 'factoryBeanObjectType': java.lang.String’

这个错误需要将mybatis的版本修改


      
        org.mybatis.spring.boot
        mybatis-spring-boot-starter
        
        3.0.3 
    

8、tomcat版本错误

    'void org.apache.catalina.Context.addServletContainerInitializer(jakarta.servlet.ServletContainerInitializer, java.util.Set)'

The calling method's class, org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory, was loaded from the following location:

    jar:file:/D:/Software/repository/org/springframework/boot/spring-boot/3.2.3/spring-boot-3.2.3.jar!/org/springframework/boot/web/embedded/tomcat/TomcatServletWebServerFactory.class

The called method's class, org.apache.catalina.Context, is available from the following locations:

jar:file:/D:/Software/repository/org/apache/tomcat/embed/tomcat-embed-core/9.0.73/tomcat-embed-core-9.0.73.jar!/org/apache/catalina/Context.class

springboot3.x后。tomcat版本也要对应修改,我这边是因为制定了版本,去掉指定即可

 
        
        
        
  

9、redis链接错误

严重: Servlet.service() for servlet [dispatcherServlet] in context with path [/activitymgr] threw exception
org.springframework.data.redis.RedisConnectionFailureException: Unable to connect to Redis
    at org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory$ExceptionTranslatingConnectionProvider.translateException(LettuceConnectionFactory.java:1795)
    at org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory$ExceptionTranslatingConnectionProvider.getConnection(LettuceConnectionFactory.java:1726)
    at org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory$SharedConnection.getNativeConnection(LettuceConnectionFactory.java:1528)
    at org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory$SharedConnection.lambda$getConnection$0(LettuceConnectionFactory.java:1508)
    at org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory.doInLock(LettuceConnectionFactory.java:1469)

这个是因为springboot3以后的版本redis配置变了
sring.redis变为spring.data.redis

10、 javax.xml.bind.DatatypeConverter找不到

Caused by: java.lang.ClassNotFoundException: javax.xml.bind.DatatypeConverter
    ... 94 more
jakarta.servlet.ServletException: Handler dispatch failed: java.lang.NoClassDefFoundError: javax/xml/bind/DatatypeConverter

pm.xml加上

        
        javax.xml.bind
        jaxb-api
        2.3.0
    
    
        com.sun.xml.bind
        jaxb-impl
        2.3.0
    
    
        com.sun.xml.bind
        jaxb-core
        2.3.0
    
    
        javax.activation
        activation
        1.1.1

11、freemarker页面取session的值的问题

发现freemarker直接取session取不了了,要从session中取出来然后设置到request中

12、sun.misc.BASE64Encoder和sun.misc.BASE64Decoder的替代

这两个类是sun公司的内部方法,并没有在java api中公开过,不属于JDK标准库范围,java8后已经弃用了,这里可以用java.util。Base64来替代

Base64.Encoder base64Encoder = Base64.getEncoder();
Base64.Decoder base64Decoder = Base64.getDecoder();

12、GLIBC版本问题

Error: dl failure on line 542
Error: failed /home/ssmuser/activity_mgr_new/jdk-17.0.2/lib/server/libjvm.so, because /lib64/libc.so.6: version `GLIBC_2.6' not found (required by /home/ssmuser/activity_mgr_new/jdk-17.0.2/lib/server/libjvm.so)

jdk17需要2.6的版本,但是目前系统的版本是2.5.

查看目前系统的版本

ldd --version
ldd (GNU libc) 2.5
Copyright (C) 2006 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Written by Roland McGrath and Ulrich Drepper.

尝试备份服务器升级到2.6

tar -zxvf glibc-2.6.tar.gz

mkdir build
cd build
../configure --prefix=/usr --disable-profile --enable-add-ons --with-headers=/usr/include --with-binutils=/usr/bin
make && make install

继续启动程序然后报缺失2.7,继续尝试升级,然后执行jps等java命令直接报段错误,尝试重启虚拟机,也不行

13、生成环境glibc版本

发现生产环境glibc版本为2.12,更加低,几乎没有机会升级到2.7,因此该升级方案失败。

二、直接升级结果失败

代码升级成功,本地启动测试成功,开发环境启动jdk17发现GLIBC需要2.7,开发环境为2.5升级到2.7后相关java启动命令报段错误,暂时没有解决,生成环境GLIBC为2.12,估计更加难升级2.7. 因此除非服务器环境支持,否则难以升级到springboot3.2.3的版本。

三、替换相关jar包升级

         
        
            org.springframework
            spring-web
            5.3.32
        
        
            org.springframework
            spring-webmvc
            5.3.32
        
        
            org.springframework
            spring-aop
            5.3.32
        
        
            org.springframework
            spring-beans
            5.3.32
        
        
            org.springframework
            spring-context
            5.3.32
        
        
            org.springframework
            spring-context-support
            5.3.32
        
        
            org.springframework
            spring-core
            5.3.32
        
        
            org.springframework
            spring-expression
            5.3.32
        
        
            org.springframework
            spring-jcl
            5.3.32
        
        
            org.springframework
            spring-jdbc
            5.3.32
        
        
            org.springframework
            spring-oxm
            5.3.32
        
        
            org.springframework
            spring-tx
            5.3.32
        
        

该方案可行。

四、结论

如果你的服务器GLIBC能升级到2.7可以尝试直接升级版本,如果不行可能就得升级相关jar包。当然升级相关jar包的后果就是你的springboot以后也很难从2.x到3.x了。

最近发表
标签列表