Central 上的 Spring 5.3.41 不是官方发的:逐字节比对,官方修两条它少一条

一个搜得到的 5.3.41

Spring Framework 5.3 线的开源支持在 2024-08-31 结束,Maven Central 上 org.springframework 的 5.3 线终版是 5.3.39 。之后的 5.3.40 ~ 5.3.50,官方安全公告里都标着 Enterprise Support Only,只发给商业支持客户。

(这一点上一篇实测过:Spring 5.3.41 在哪下载?)

但如果你在 Central 上按版本搜 spring-core 的 5.3.4x,会搜到一个结果:

makefile 复制代码
net.xdob.springframework:spring-core:5.3.41   2025-03-12

同一个 groupId 下一共 23 个构件,spring-webspring-webmvcspring-context、BOM 都有,版本是 5.3.39 和 5.3.41。在 Central 上,5.3.4x 的 Spring 只有这一家。

它下载下来的文件名是 spring-core-5.3.41.jar,MANIFEST 里写的是 Implementation-Version: 5.3.41,和官方构件的格式一模一样。放进项目里,凡是按 jar 文件名或 MANIFEST 认版本的工具,看到的都是「Spring 5.3.41」;只有去看 groupId 的,才会发现它不是 org.springframework

那它到底是什么?

它是谁发的

打开 Central 上的 POM:

xml 复制代码
<groupId>net.xdob.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>5.3.41</version>
<url>https://github.com/dibyang/spring-framework</url>
<organization>
  <name>Spring IO</name>
</organization>
<developers>
  <developer>
    <id>jhoeller</id>
    <name>Juergen Hoeller</name>
  </developer>
</developers>

urlscm 指向的是 GitHub 上的 dibyang/spring-framework:一个从官方仓库 fork 出来的个人仓库,描述是 "Spring Framework for fix vulnerability"。organizationdevelopers 沿用的是官方 POM 里的写法。

所以第一个结论:这是第三方基于官方源码自行重编、发到 Central 的,不是 Spring 官方发布。 仓库描述写得很清楚,它的目的就是给停更的 5.3 线补漏洞。

源码差了什么:6 个提交,1 个动了 Java

先确认官方 5.3.x 分支的状态:

bash 复制代码
gh api repos/spring-projects/spring-framework/compare/v5.3.39...5.3.x
# ahead_by: 0

官方开源的 5.3.x 分支头就是 v5.3.39 标签,之后没有公开提交。

再比 fork 的 5.3.x 分支:

提交 内容
add ali maven 构建脚本
v5.3.39 构建与发布配置
v5.3.41-SNAPSHOT 改版本号
fix CVE-2024-38819 改了 WebMvc.fn / WebFlux.fn 的两个 PathResourceLookupFunction
v5.3.41 改版本号
up 发布配置

6 个提交里,只有 1 个改了 Java 代码。

逐字节比对:它和 5.3.39 有多少不同

光看提交不够,发到 Central 的 jar 才是真正进项目的东西。把 net.xdob 的 5.3.41 和官方 5.3.39 逐个类算 SHA-256:

构件 类总数 与官方 5.3.39 不同的类
spring-core 978 0
spring-context 892 0
spring-webmvc 557 1(PathResourceLookupFunction)
spring-webflux --- 1(PathResourceLookupFunction)

spring-corespring-context 与官方 5.3.39 逐字节相同。 这个 5.3.41 就是官方 5.3.39,加上一个补丁。

官方 5.3.41 修了两条,它只有一条

spring.io 看官方公告,修复版写着 5.3.41 的是这两条:

CVE 内容 官方 5.3 线修复版 GitHub Advisory 严重度 net.xdob 5.3.41
CVE-2024-38819 WebMvc.fn / WebFlux.fn 静态资源路径穿越 5.3.41(Enterprise Support Only) high 7.5 有补丁(写法与官方不同,见下文)
CVE-2024-38820 DataBinderdisallowedFields 大小写转换受 Locale 影响,字段可能没被挡住 5.3.41(Enterprise Support Only) medium 5.3 没有

38820 的严重度不高,触发前提是应用用 setDisallowedFields 挡了某些字段。但问题不在这一条本身,而在于:版本号写着 5.3.41,却不包含官方 5.3.41 的全部修复。

少修的那条,在字节码里怎么认出来

38820 的官方补丁在 DataBinder 里。拿官方开源的 6.1.13(修复前)和 6.1.14(修复后)比:补丁把 toLowerCase() 换成了 toLowerCase(Locale.ROOT),于是类的常量池里多了对 java/util/Locale 的引用。

但只看这一个特征会误判。6.1.20 修 CVE-2025-22233 时,这段又被重构成 PatternMatchUtils.simpleMatchIgnoreCase,Locale 引用随之消失。补丁有两种字节码形态。

把 Central 上这几条线的开源版全扫一遍:

版本 引用 java/util/Locale 引用 simpleMatchIgnoreCase
5.3.36 ~ 5.3.39
6.0.20 ~ 6.0.23
6.1.10 ~ 6.1.13
6.1.14 ~ 6.1.19
6.1.20 ~ 6.1.21
net.xdob 5.3.41

修复前的每一版两种都没有,修复后的每一版至少有一种。net.xdob 的 5.3.41 两种都没有,它的 DataBinder 本来就和 5.3.39 逐字节相同。

按版本号 5.3.41 对漏洞清单,会少算什么

很多团队的流程是:SCA 报出版本号,再拿版本号去对公告的影响区间。拿 5.3.41 去对,会得出「38819、38820 已修」,而实际只修了一条。

另外两件事也要一起看:

  1. CVE-2024-38816 (静态资源路径穿越,high 7.5)官方在 5.3.40 修。官方 6.1.13 的补丁是新增了 isInvalidEncodedInputPath 方法,net.xdob 的构件里没有这个方法,它是在 apply 里加了一次 cleanPath两种写法是否等效,本文没有验证。
  2. 5.3.41 之后官方又出了十几条 5.3 线的修复:CVE-2024-38828(5.3.42)、CVE-2025-22233(5.3.43)、CVE-2025-41242(5.3.44)、CVE-2025-41249(5.3.45),以及 2026-06-08 那批(5.3.49)和 2026-08-20 那批(5.3.50)。这个包发布于 2025-03,结构上一条都不可能包含。

顺带一个细节:一行调试输出

net.xdob 的 Spring MVC 补丁里,PathResourceLookupFunction.isInvalidPath 多了一行:

java 复制代码
System.out.println("path = " + path);

如果你用函数式路由 RouterFunctions.resources(...) 发静态资源,每个命中该路由的请求路径都会打到标准输出。用传统 addResourceHandlers 配置的项目不走这段代码。这一行也正好成了认出这个构件的指纹:官方任何开源版的这个类里都没有 "path = " 这个字符串。

自己核:扫一下构件就知道

spring-cvss-check v0.3.0 加了「字节码核验」:不看版本号,直接看补丁在不在。

bash 复制代码
java -jar spring-cvss-check.jar target/
# Spring Boot fat jar 也行,会打开 BOOT-INF/lib 里的依赖
java -jar spring-cvss-check.jar app.jar

扫到 net.xdob 的 5.3.41 时的输出:

ini 复制代码
== 字节码核验:版本号说修了,补丁在不在 ==
  [对不上]  spring-context 5.3.41
            版本号 5.3.41 按官方公告应已修 CVE-2024-38820,但 DataBinder 里**找不到这个补丁**
  [对不上]  spring-webmvc 5.3.41
            带 net.xdob 第三方重编指纹:PathResourceLookupFunction.isInvalidPath 里有一行 System.out.println("path = " + path)

发布前拿官方开源 5.3.39、6.1.13、6.1.14、6.1.21 逐个跑过,核验项都是 0 条。第一版只认 Locale,把官方 6.1.21 误报成了补丁不在,上面那张两种形态的表就是修这个误报时扫出来的。核验只对 5.3 / 6.0 / 6.1 三条线下结论,6.2 以后不判。

纯 Java,零依赖,不联网。

这篇能证明什么、不能证明什么

能证明的:

  • Central 上能下到的 Spring 5.3.41 来自第三方 net.xdob.springframework,不是官方发布;
  • 它的 spring-corespring-context 与官方 5.3.39 逐字节相同;
  • 官方 5.3.41 修的 CVE-2024-38820,它没有。

不能证明的:

  • 不是说发布者有恶意。仓库描述写明了目的就是补漏洞,只是只补了一条;
  • 不是说 38820 是高危。GitHub Advisory 标 medium,要求应用用了 disallowedFields;
  • 不是说它的 38819 补丁无效。写法和官方不同,等效与否没有验证;
  • 官方商业版 5.3.41 的补丁长什么样,我们拿不到构件,上文的补丁形态只来自开源版。

实际建议只有一句:别把它当官方 5.3.41,别按这个版本号去对漏洞清单。

相关推荐
用户094248568031 小时前
第8章:Java 内存模型(JMM)入门——可见性、有序性、原子性
java·jvm
AI深栈1 小时前
第 9 章 · Model Context Protocol(MCP)
java·人工智能
雨辰AI1 小时前
信创多租户项目 9 大踩坑|数据隔离失效、权限越权终极解决(金仓 / 达梦 / 高斯全库适配)
java·大数据·数据库·后端
captain3761 小时前
网络原理(4)-TCP ▲▲▲
java·服务器·网络·网络协议·tcp/ip
橙子圆1231 小时前
JUC之线程和进程
java
Bs_MoneyMagnet1 小时前
基于springboot+vue的旅游行程分享与推荐小程序的设计与实现 源码+文档
java·vue.js·spring boot·后端·微信小程序·毕业设计·计算机毕业设计
一技安身1 小时前
【信创】统信UOS 银河麒麟离线部署Python3.11完整方案
android·java·python3.11
陈皮波比茶1 小时前
k8s 快速入门
java·kubelet
Json____2 小时前
基于 Spring Boot + Vue3 的校园自习室座位预约系统实战
java·管理系统·it学习·wwwoop.com