老炮踩坑录 · F07 · 翻车现场系列
· 基于「企业融合评估平台」真实源码,拆解2022年的 Spring Boot 项目
· 关键词:Spring Boot 停更 · 依赖漏洞 · 安全裸奔 · 版本债务
引子
打开 pom.xml 的那一刻,我以为自己看错了。
xml
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.0.RELEASE</version>
</parent>
2.1.0.RELEASE,我查了一下这个版本的生日------2018 年 10 月 30 日。
那一年,Java 11 刚发布,大家还在讨论 Java 8 要不要升级;那一年,Spring Boot 还是 Pivotal 的产品,VMware 还没接手;那一年,这个版本号看起来挺新挺潮。
但现在是 2026 年。
这个版本已经停维护5年多了。
不是"不再推荐",不是"建议升级"------是彻底死了:OSS 免费支持 2019 年 10 月终止,商业付费支持 2021 年 1 月终止。从 2021 年至今,Spring 官方没有、也永远不会再为 2.1.x 发布任何安全补丁。
而这个2022年的项目,就跑在这个 "停维护这5年多" 的版本上。
一张"死亡证明"
在讲具体风险之前,先给这个项目出一份完整的"体检报告"。
框架层
| 项 | 项目实际版本 | 当前最新 | 落后多少 |
|---|---|---|---|
| Spring Boot | 2.1.0(2018-10) | 4.1(2026-06) | 跨了 3.x、4.x 两个大版本 |
| Spring Framework | 5.1.2(Boot 2.1.0 内置) | 6.2.x | 跨了 5.3、6.0、6.1、6.2 四条线 |
| Java | 1.8(2014 年发布) | 21 LTS(2023)/ 26(2026-03) | 跨了 12 个 JDK 版本 |
| Tomcat | 9.0.12(Boot 2.1.0 内置) | 11.0.x | 跨了 10.x、11.x |
依赖层
| 依赖 | 项目版本 | 发布年份 | 当前最新 | 状态 |
|---|---|---|---|---|
| fastjson | 1.2.37 | 2018 | 2.0.x | 🔴 已知 RCE 远程代码执行漏洞 |
| guava | 20.0 | 2016 | 33.x | 🟡 落后 10+ 个大版本 |
| POI | 3.12 | 2015 | 5.3.x | 🟡 落后 8 年,多个 bugfix 未合入 |
| Swagger (springfox) | 2.9.2 | 2018 | 已废弃,社区迁移至 SpringDoc | 🔴 项目已停止维护 |
| commons-collections | 3.2.1 | 2015 | 4.4 | 🔴 反序列化漏洞 CVE-2015-7501 |
| commons-fileupload | 1.3 | 2013 | 2.x | 🔴 路径穿越漏洞 |
| druid | 1.1.13 | 2018 | 1.2.x | 🟡 落后 6 年 |
| mybatis-plus | 3.3.0 | 2019 | 3.5.x | 🟡 落后 5 年 |
| commons-lang | 2.6 | 2011 | 3.x | 🟡 已迁入 commons-lang3,2.x 停更 |
| json-lib | 2.2.3 | 2008 | 无 | 🔴 2008 年的库,已无人维护 |
源码来自项目
pom.xml,版本号可直接验证。
10 个依赖里,4 个有已知安全漏洞(红标) ,6 个严重过时(黄标)。
这不是"技术旧了一点"的问题。这是安全裸奔。
三层裸奔
我把这个项目的风险分成三层,从外到内,一层比一层致命。
第一层:框架层------永远等不到补丁
Spring Boot 的版本支持策略很残酷:每个大版本只维护约 1 年 OSS 支持 + 1 年商业支持,然后彻底放弃。

看看 Spring boot 官方的这张支持时间线。2.1.x 的绿色和黄色在 2021 年初就断了,而我参与的那个 2022 年的项目,正好落在了这根断崖线上。
yaml
2.1.x ──── 2019.10 OSS 终止 ──── 2021.01 商业终止 ──── 永远没人管
↑
我的项目在这里
这意味着什么?
从 2021 年 1 月至今,Spring Framework 每修一个安全漏洞,你的项目都吃不到。
这不是假设。停维护这5年多里,Spring Framework 修了十几个安全漏洞:
- CVE-2022-22965(Spring4Shell) :Spring MVC 远程代码执行,CVSS 9.8 满分。影响所有 5.3.x 之前的版本------包括你用的 5.1.2。
- CVE-2022-22950:Spring Web 路径穿越漏洞,攻击者可以读取服务器任意文件。
- CVE-2023-20861:Spring Expression 注入,可以绕过安全认证执行任意代码。
- ......还有更多。
这些漏洞的修复代码都在 GitHub 上,任何人都能看到。攻击者能看到,你的项目却收不到。
因为你的版本,已经死了。
第二层:依赖层------CVE 排队等
框架不维护了,第三方依赖也在"摆烂"。
最典型的是 fastjson 1.2.37。
fastjson 1.2.37 有一个远程代码执行(RCE)漏洞 ------攻击者构造一段特殊的 JSON 字符串发给你的接口,就能在你的服务器上执行任意 Java 代码。不是理论风险,是已经被武器化、被大规模利用的漏洞。
而这个项目里,fastjson 被用在了 Controller 层做 JSON 解析:
less
// 项目代码中大量使用 fastjson 解析前端数据
import com.alibaba.fastjson.JSONObject;
@PostMapping("/submit")
public Result submit(@RequestBody JSONObject data) {
String companyId = data.getString("companyId");
// ...
}
每一个接收 @RequestBody JSONObject 的接口,都是潜在的攻击入口。
第三层:部署层------WAR 包锁死升级之路
xml
<packaging>war</packaging>
项目打成 WAR 包,部署到外置 Tomcat。
这种方式在 2018 年还算主流,但在 2026 年已经是"古董级"部署了。Spring Boot 3.x 甚至已经不再推荐 WAR 包部署方式。
WAR 包部署的问题不在于它"不能用",而在于:
- 升级框架几乎不可能:外置 Tomcat 版本和 Spring Boot 内置版本经常不一致,升级 Boot 版本意味着重新适配整个部署链路
- 无法容器化:现在主流的 K8s/Docker 部署都基于 fat jar,WAR 包要先改造部署方式才能上云
- 安全补丁滞后:外置 Tomcat 的安全补丁需要运维手动更新,而不是随框架一起升级
这一层不直接产生漏洞,但它锁死了你升级的可能性。想修复第一层、第二层的问题?对不起,部署方式就不让你动。
为什么这种老项目不敢升级?
说完风险,说说原因。
不是没人知道该升级,而是每一次想到升级都被现实打了回来:
"升个 Boot 版本,javax 全变 jakarta 了。"
Spring Boot 3.0 把整个 javax.* 命名空间迁移到了 jakarta.*。这不是改几行 import 的事------项目里每一个用了 javax.servlet、javax.validation、javax.annotation 的文件都要改。
"升了 Boot,mybatis-plus 也要升,升了之后 API 变了。"
依赖之间是联动的。Boot 3.x 要求 mybatis-plus 3.5.x,而 3.5.x 的部分 API 和 3.3.0 不兼容。升一个,带一串。
"项目跑得好好的,为什么要升?"
这句话是最大的陷阱。"跑得好好的"只是表面上没出事。安全漏洞不是 bug------它不会报 500,不会崩线程,不会在测试环境暴露。它安安静静地躺在代码里,等着被扫描、被利用。
直到出事那天,才有人问:"为什么我们的版本这么老?"
你的项目是不是也在裸奔?
别光看我的项目。打开你自己的 pom.xml,对照这个清单排查一遍:
| 检查项 | 怎么查 | 危险信号 |
|---|---|---|
| Spring Boot 版本 | 看 <parent> 里的 version |
2.x 全系列已 EOL,3.0-3.2 也已 EOL |
| Java 版本 | 看 <java.version> |
1.8 = 12 年前的 Java,3.x 已不支持 |
| fastjson | 搜 fastjson |
1.x 全系列有 RCE 风险,应迁移到 2.x 或 Jackson |
| 裸 @Transactional | 搜 @Transactional 不带 rollbackFor |
受检异常不回滚(上期文章讲过) |
| OWASP 检查 | 看有没有 dependency-check 插件 | 没有 = 连安检门都没装 |
| 部署方式 | 看 <packaging> |
WAR = 升级之路被锁死 |
如果中了两条以上,你的项目可能也在裸奔。
老炮点评
这个坑的本质不是"技术债"三个字能概括的。
技术债是你知道欠了,有计划还 。但'版本停维护5年还在跑'不是技术债------是技术盲区。团队里可能压根没人知道 2.1.0 早就 EOL 了,没人去查过 Spring 的支持时间线,没人跑过一次 OWASP 扫描。
最可怕的不是漏洞,是"不知道有漏洞"。
升级?当然要升。
但不是今天改一行、明天改一行的"温水煮青蛙"。升级需要完整规划:先跑 OWASP 扫描拿到漏洞清单,再评估哪些能热修复、哪些必须升版本,最后制定迁移计划。
下期我就来做这件事------把这个项目从 2.1.0 升级到 3.x,看看一路上要踩多少坑。
下期预告:《Spring Boot 2.1.0 → 3.x 迁移实战:我踩了多少坑》
上期我说这个项目在裸奔,这期我来填坑。从
javax到jakarta,从 fastjson 到 Jackson,从 WAR 包到 fat jar------一个2022 年的老项目,迁移全过程实录。下一篇是真正的"硬仗",建议收藏等更新。
我是老炮,18 年 Java 老兵,仍在一线。关注「Java老炮踩坑录」,不错过每一篇真实案例,少踩坑。