Spring Cloud Config 在 2026-05-07 公布了 CVE-2026-40982:spring-cloud-config-server 存在目录穿越,无需认证,可读取服务器上的任意文件。
这个洞本身不算稀奇。真正让我意外的是去查怎么修的时候 ------ 有三条版本线的修复版,在 Maven Central 上根本不存在。
官方给的修复版,一半是买不到的
先看官方 advisory 原文列的修复版本:
| 版本线 | 修复版 | 官方标注 |
|---|---|---|
| 3.1.x | 3.1.14 | Enterprise Support Only |
| 4.1.x | 4.1.10 | Enterprise Support Only |
| 4.2.x | 4.2.7 | Enterprise Support Only |
| 4.3.x | 4.3.3 | OSS |
| 5.0.x | 5.0.3 | OSS |
「Enterprise Support Only」这几个字很容易被扫过去。它的实际含义是:这三个版本只发给买了商业支持的客户,不会出现在 Maven Central 上。
自己验一下,一条 curl 就够:
bash
curl -sI https://repo1.maven.org/maven2/org/springframework/cloud/spring-cloud-config-server/4.2.7/
# HTTP/1.1 404 Not Found
3.1.14、4.1.10 一样是 404。
对照 Maven Central 上这几条线实际能拿到的最高版本:
| 版本线 | 公开仓库最高版 | 官方要求升到 | 差距 |
|---|---|---|---|
| 3.1.x | 3.1.10 | 3.1.14 | 差 4 个版本 |
| 4.1.x | 4.1.7 | 4.1.10 | 差 3 个 |
| 4.2.x | 4.2.4 | 4.2.7 | 差 3 个 |
也就是说:如果你在这三条线上,把小版本升到顶,你依然是受影响的。
查版本时别用 search.maven.org 的 solrsearch 接口 ------ 我查的时候它说这个构件最新版是 4.3.0,而 repo1.maven.org 的 maven-metadata.xml 里明明白白是 5.0.4。两个数据源打架时,以 repo1 的 metadata 为准,它才是仓库本身。
为什么你的扫描器不会提醒你这件事
这一段是我觉得最值得说的。
看 GitHub advisory GHSA-6g23-24mc-hx6x 的结构化数据:
json
{"range": "<= 3.1.13", "first_patched_version": null}
{"range": ">= 4.1.0, <= 4.1.9", "first_patched_version": null}
{"range": ">= 4.2.0, <= 4.2.6", "first_patched_version": null}
{"range": ">= 4.3.0, <= 4.3.2", "first_patched_version": "4.3.3"}
{"range": ">= 5.0.0, <= 5.0.2", "first_patched_version": "5.0.3"}
前三条的 first_patched_version 是 null。
Dependabot、OSV 以及一大批 SCA 工具消费的正是这份数据。它们的核心逻辑是「当前版本 → 建议升到 first_patched_version」,而这里没有可升的目标。
所以这三条线上的用户,大概率既不会收到一个可执行的升级建议,也不会被明确告知「你这条线没有免费补丁」。信息不是被藏起来了,是它落在了数据结构的空档里。
说清楚边界,免得我自己也说过头:这不是 「Dependabot 对这个 CVE 完全不管」。对 4.3.x / 5.0.x,它能正常给出 4.3.3 / 5.0.3。问题只出在那三条 null 的线上。
那这三条线该怎么办
只有两条路,没有第三条:
- 跨版本线升级 ------ 升到 4.3.3+ 或 5.0.3+。这不是小版本升级,要过 Spring Boot / Spring Cloud release train 的兼容性,该测就得测。
- 买商业支持(Tanzu Spring),拿 3.1.14 / 4.1.10 / 4.2.7。
在升级窗口期之前,至少先把暴露面收掉:Config Server 不要直接暴露在公网 ,前面挂网关并对 /{application}/{profile} 这类路径做鉴权。目录穿越再狠,打不到也没用。
顺便:一个很容易搞混的点
spring-cloud-config-server 是服务端。本 CVE 只影响它。
而 spring-cloud-starter-config 是客户端 (你的业务服务用它去 Config Server 拉配置),不受这个漏洞影响。
按 GitHub 代码搜索,pom.xml 里出现 spring-cloud-config-server 的仓库约 2.4 万 ,而出现 spring-cloud-starter-config 的约 9.9 万 ------ 也就是说,大部分看到这条 CRITICAL 而紧张的人,其实并不受影响。 先分清自己是哪一边。
写了个小工具
scc-check,零依赖单 jar,离线跑:
bash
java -jar scc-check.jar /opt/apps # 扫目录
java -jar scc-check.jar myapp.jar # 扫 Spring Boot fat-jar
java -jar scc-check.jar target/ --utf8 # Windows 中文乱码时加这个
它和一般 SCA 的区别就是多输出一列:你这条线在公开仓库里有没有能升的安全版。
scss
[CRITICAL] /opt/apps/config-server.jar
版本 4.2.4(4.2 线,依据: Maven 元数据(pom.properties))
受影响。官方修复版属 Enterprise Support,Maven Central 上不存在
(该线公开最高版仅 4.2.4)。唯一出路:跨版本线升到 4.3.3+ 或 5.0.3+,
或购买商业支持。
线 受影响区间 官方修复版 OSS最高 公开仓库能升到安全版吗
3.1 <= 3.1.13 (未给出) 3.1.10 不能 ------ 仅商业支持
4.1 4.1.0 ~ 4.1.9 (未给出) 4.1.7 不能 ------ 仅商业支持
4.2 4.2.0 ~ 4.2.6 (未给出) 4.2.4 不能 ------ 仅商业支持
4.3 4.3.0 ~ 4.3.2 4.3.3 4.3.4 能
5.0 5.0.0 ~ 5.0.2 5.0.3 5.0.4 能
几个刻意的取舍:
- 判定表是生成的,不是手抄的。 一个脚本从 GitHub advisory 和 repo1.maven.org 的 metadata 直接编译成 Java 表,并带断言:区间数不足、null 的条数不对、版本线解析不出来,直接中止,不生成文件。手抄的表在源数据变化时不会报错,只会安静地过期。
- 不判 4.0.x。 advisory 的任何区间都没覆盖 4.0.x(4.0.0 > 3.1.13,不落在无下界那条里)。工具只报「不在官方覆盖范围内」,不报 CRITICAL ------ 靠推测填判定表,会让人做错决定。
- 读不出版本时明说「判不了」。 Spring Cloud 用 release train BOM 统一管版本,pom.xml 里常常根本没有
<version>;scope 是 test / provided 的不传递;被 XML 注释包住的依赖会被剥掉。这几种情况都不会被当成「安全」。
它不是什么
- 不是通用 SCA,只查这一个 CVE。
- 只做版本比对,不检测你的 Config Server 是否真的暴露在公网、有没有 WAF。判定结果是排查起点,不是安全结论。
- CVSS 官方给的是 8.2 (High)(GitHub 那边标 critical,以 spring.io 为准)。
地址
MIT,我写的。31 个单元测试,并用 Maven Central 上真实的 3.1.10 / 4.2.4 / 5.0.4 三个构件复验过判定结果。
发现误报或漏报请提 issue。 安全工具最怕让人误以为安全,任何一条误判都值得提。