文中的数字都是 2026-10-13 读到的。GitHub 的审核状态和 Spring Boot 的版本会变,结论请以你看到这篇文章当天的实际情况为准。
先说结论
Tomcat 官方在 2026 年 8 月和 9 月各修了一批漏洞,共 22 条:
| 批次 | 条数 | 修复版 |
|---|---|---|
| 8 月批 | 10 | 9.0.121 / 10.1.58 / 11.0.25 |
| 9 月批(官方写 2026-09-23 公开) | 12 | 9.0.122 / 10.1.60 / 11.0.26 |
三件事:
-
这 22 条里有 19 条,GitHub 上还是
unreviewed。 GitHub 只拿reviewed的 advisory 做 Dependabot 告警,所以按规则这 19 条进不了你的告警列表。 -
各条 Spring Boot 线最新版自带的 Tomcat,都落在受影响区间里:
Spring Boot(该线 Maven Central 上最新) 自带 tomcat.version9 月批修复版 3.5.16 10.1.55 10.1.60 4.0.8 11.0.24 11.0.26 4.1.1 11.0.24 11.0.26 3.4.13 10.1.50 10.1.60 2.7.18 9.0.83 9.0.122 -
其中一条是修上一个洞时带进来的。
CVE-2026-86350,官方评 Important,原文:Inconsistent interpretation of HTTP/2 requests caused by a regression in fix for CVE-2026-41293 can trigger request header mix-up.
它的受影响区间是 9.0.118--9.0.121、10.1.55--10.1.59、11.0.22--11.0.25 ------ 正好是
CVE-2026-41293的修复版自己。也就是说,当初为了修 41293 升到 9.0.118 / 10.1.55 / 11.0.22 的,需要再升一次。
但先别慌:这 22 条没有一条是默认配置就中的。 每一条都有前提,下面逐条列。
86350 要不要管:看你开没开 HTTP/2
这条的前提是启用了 HTTP/2。Spring Boot 默认不开 ------ 官方属性表里 server.http2.enabled 的默认值是 false。
所以:
- 配置里没有
server.http2.enabled=true,也没有自己给连接器加 HTTP/2 升级协议 → 这条跟你无关。 - 开了 → 你的 Tomcat 在上面那个区间里就中,升到 9.0.122 / 10.1.60 / 11.0.26。
同样以 HTTP/2 为前提的还有 3 条:CVE-2026-68763(Important,流被重置时的分配泄漏,可致拒绝服务)、CVE-2026-77762(Low)、CVE-2026-78437(Low)。
用了 WebSocket 的,有 5 条
| 编号 | 官方评级 | 前提 |
|---|---|---|
| CVE-2026-76183 | Important | 有 WebSocket 端点,且对端点路径配置了 security-constraint。请求路径被错当成端点模板解析,可以绕过约束 |
| CVE-2026-77791 | Important | 有 WebSocket 端点。发送关闭消息时的忙等可被用来做拒绝服务 |
| CVE-2026-79677 | Moderate | 有 WebSocket 端点并使用异步写。并发缺陷导致写超时丢失 |
| CVE-2026-87022 | Low | 启用了 per-message-deflate 压缩扩展 |
| CVE-2026-73180 | Low | WebSocket 连接建立在已认证的 HTTP 会话之上 |
一个细节:内嵌形态下,WebSocket 的实现不在 tomcat-embed-core 里,在单独的 tomcat-embed-websocket 里(下真 jar 列 class 验过)。spring-boot-starter-web 会把它带进来;如果你的项目把它排除了,这 5 条对你不适用。
其余 13 条的前提
| 编号 | 官方评级 | 前提 |
|---|---|---|
| CVE-2026-78383 | Important | 启用了 AJP 连接器 |
| CVE-2026-65182 | Important | 较长路径的 security-constraint 写在更严格的较短子路径约束之前 |
| CVE-2026-65927 | Important | 配置了 RewriteValve 且规则用了 [N] 标志 |
| CVE-2026-68569 | Important | DataSourceRealm / JDBCRealm 搭配 CLIENT-CERT、SPNEGO 这类认证方式 |
| CVE-2026-65637 | Moderate | 启用 HTTP/2 且依赖严格 SNI 检查 |
| CVE-2026-73581 | Moderate | 用 OpenSSL / OpenSSL-FFM 的 TLS 实现、证书放在 keystore 且配置了 CRL |
| CVE-2026-86248 | Moderate | FFM 版 OpenSSL + CLIENT_CERT 认证 + 关闭了 OCSP soft-fail(tomcat-embed-core 里没有 FFM 那部分类,内嵌用户不涉及) |
| CVE-2026-65905 | Low | 配置了 DIGEST 认证 |
| CVE-2026-68525 | Low | FORM 认证,且约束按 HTTP 方法区分 |
| CVE-2026-66422 | Low | web.xml 里定义了 security-role-ref |
| CVE-2026-65183 | Low | 连接器监听 Unix Domain Socket |
| CVE-2026-75973 | Low | SimpleAuthConfigProvider 被配成默认 Jakarta Authentication provider 且多个 web 应用共用 |
| CVE-2026-77756 | Low | Tomcat 位于反向代理之后 |
HTTP/2 的 4 条、WebSocket 的 5 条,加上这 13 条,就是全部 22 条。
三条已经是 reviewed、Dependabot 会报的是:65182、65905、68525。其余 19 条目前是 unreviewed。
为什么说「进不了告警」
GitHub 的 advisory 有两种状态。reviewed 的带着受影响的包坐标和版本区间,Dependabot 拿它和你的依赖对;unreviewed 的是从 NVD 自动导入、还没人工确认受影响包的条目,包列表是空的。
这是正常的流程状态,不是谁的疏漏。只是在它转成 reviewed 之前,你的告警列表里看不到它 ------ 而 9 月这批已经公开 20 天了。
你可以自己查任意一条的状态:
bash
gh api "advisories?cve_id=CVE-2026-86350" --jq '.[] | .type, (.vulnerabilities | length)'
2026-10-13 的返回是 unreviewed 和 0。
怎么知道自己带的是哪个版本的 Tomcat
Spring Boot 项目的 pom 里通常没有 Tomcat 的版本号,它由 spring-boot-starter-parent 管着。两个办法:
bash
mvn dependency:tree -Dincludes=org.apache.tomcat.embed
Spring Boot 3.5.16 的最小工程跑出来是:
\- org.springframework.boot:spring-boot-starter-web:jar:3.5.16:compile
\- org.springframework.boot:spring-boot-starter-tomcat:jar:3.5.16:compile
+- org.apache.tomcat.embed:tomcat-embed-core:jar:10.1.55:compile
+- org.apache.tomcat.embed:tomcat-embed-el:jar:10.1.55:compile
\- org.apache.tomcat.embed:tomcat-embed-websocket:jar:10.1.55:compile
或者直接扫构建产物。我之前写过一个离线小工具 tomcat-check,这次把这两批补进去了(v0.2.0):
bash
java -jar tomcat-check.jar target/my-app.jar
下面是对 Spring Boot 3.5.16 默认依赖(tomcat-embed-core / -el / -websocket 10.1.55)实跑的小结:
构件:tomcat-embed-core 版本:10.1.55 (版本号取自 MANIFEST)
CVE-2026-86350 Regression in fix for CVE-2026-41293 can trigger request header mix-up
评级:ASF 官方 Important │ GitHub 尚未评级
进不了告警:GitHub advisory 仍是 unreviewed(未标注受影响包),Dependabot 只用 reviewed 的做告警
触发条件:仅当启用 HTTP/2
官方原文:Inconsistent interpretation of HTTP/2 requests caused by a regression in fix for CVE-2026-41293 can trigger request header mix-up.
── 小结 ──
命中 25 条,其中 22 条你的 Dependabot 大概率不会告警
默认配置即暴露:CVE-2026-55276
升到高于 10.1.59 的版本可覆盖以上全部条目
25 条是 2026 年全年落在 10.1.55 上的条目数(不只这两批),「命中」的意思是版本落在官方 Affects 区间内,不等于可被利用 ------ 每条下面都印着触发条件。默认配置即暴露的只有 CVE-2026-55276 一条,它是更早的条目(官方 Low)。
Boot 4.0.8 / 4.1.1 自带的 11.0.24 同样跑了一遍:命中 21 条,其中 18 条进不了告警,默认配置即暴露 0 条。
怎么升
修复版都在 Maven Central 上。用 spring-boot-starter-parent 的项目,在自己的 pom 里覆盖一个属性:
xml
<properties>
<tomcat.version>10.1.60</tomcat.version>
</properties>
实测:Spring Boot 3.5.16 的最小工程(只有 spring-boot-starter-web),不加这一行解析出来的是
tomcat-embed-core-10.1.55.jar
tomcat-embed-el-10.1.55.jar
tomcat-embed-websocket-10.1.55.jar
加上之后是
tomcat-embed-core-10.1.60.jar
tomcat-embed-el-10.1.60.jar
tomcat-embed-websocket-10.1.60.jar
再用工具扫,输出是「判定表内(2026 年)没有命中这个版本的条目」。
另外三条线同样测过(都是只有 spring-boot-starter-web 的最小工程):
| Spring Boot | 不覆盖时解析到 | 覆盖成 | 覆盖后工具输出 |
|---|---|---|---|
| 4.0.8 | 11.0.24 | 11.0.26 |
没有命中 |
| 4.1.1 | 11.0.24 | 11.0.26 |
没有命中 |
| 2.7.18 | 9.0.83 | 9.0.122 |
没有命中 |
工具与数据来源
- 工具:https://github.com/xiaoqiMikko/tomcat-check(零依赖单 jar,离线跑,Java 17+)
- 判定表不是手抄的:由脚本从
tomcat.apache.org/security-{9,10,11}.html和 GitHub Advisory API 生成,带断言;触发条件逐条对照官方描述原文 - 官方原文:https://tomcat.apache.org/security-10.html(「Fixed in Apache Tomcat 10.1.60」一节)