# CR-037　覆寫 Spring Boot BOM 之 Tomcat 版本（修補 3 個 CRITICAL）

| 項目 | 內容 |
|---|---|
| 文件編號 | CR-037 |
| 版本 | **1.0** |
| 狀態 | ✅ 已裁定並執行 |
| 提出日 | 2026-10-05 |
| 提出者 | WorkBuddy AI（開發團隊） |
| 緣起 | `#A-160`（N1 批次）之依賴漏洞掃描發現 **3 個 CRITICAL**；BEAM PMO 裁定「**Tomcat CRITICAL 修補**／目標 **11.0.26**」 |
| 關聯 | `CSP-006 §2.14`（新增）、`CSP-005 §4.3`、`docs/08-evidence/N1_工具缺口補齊與量測結果.md §2.2` |
| 嚴重度 | 🔴 **高**——`TRP-001 §6.2` 第 7 條「安全掃描無高／嚴重漏洞」**目前不達成** |

---

## 1. 問題

`#A-160` 以 `tools/scan_deps.py`（OSV）掃描 281 個外部相依，命中 **3 個 CRITICAL**，
**全部**為 `org.apache.tomcat.embed:tomcat-embed-core:11.0.24`：

| GHSA | 摘要 |
|---|---|
| `GHSA-9xv2-5v5q-p794` | DIGEST 認證器之 **Authentication Bypass by Capture-replay** |
| `GHSA-gcx9-497g-6cp6` | **Improper Access Control**／Incorrect Authorization |
| `GHSA-h3x4-894j-xpx5` | FORM 認證流程之不當授權 |

三者之 OSV 修復版本皆為 **11.0.25**。

---

## 2. 查證（`version-compat-verification` 紀律；2026-10-05 實查）

| # | 查證項 | 方法 | 結果 |
|---:|---|---|---|
| 1 | Spring Boot 4.1.x 是否已有含修復之 patch | Maven Central `spring-boot-dependencies` metadata | ❌ **只有 4.1.0／4.1.1**（無 4.1.2）→ ★ **「升 Spring Boot」不是選項，必須覆寫** |
| 2 | BOM 實際 pin 之版本 | 本地 Gradle cache 之 `spring-boot-dependencies-4.1.1.pom` | ✅ `<tomcat.version>11.0.24`——**即漏洞版本** |
| 3 | 11.0.26 是否存在且為正式版 | Maven Central metadata ＋ `downloads.apache.org` | ✅ 存在；**RELEASE-NOTES 2026-09-09**；修 **12 個安全漏洞**（非 RC／milestone） |
| 4 | 三個 embed artifact 於 11.0.26 是否齊備 | HTTP 200 檢查 POM | ✅ `tomcat-embed-core`／`-el`／`-websocket` **皆 200** |
| 5 | classpath 上實際有哪些 Tomcat artifact | `tools/scan_deps.py` 之 Gradle init script 列舉 | **恰 3 個**（`-core`／`-el`／`-websocket`，皆 11.0.24） |
| 6 | 11.0.26 是否涵蓋 11.0.25 之修復 | 同 patch line（11.0.26 > 11.0.25） | ✅ 涵蓋 |

**結論**：**覆寫 BOM 之 Tomcat 版本為 11.0.26**，並**三件 artifact 一併覆寫**。

---

## 3. 裁定

| 項目 | 內容 |
|---|---|
| 目標版本 | **11.0.26**（11.0.x patch line 之最新修補版） |
| 機制 | Gradle **專案層 `constraints`**（非 `resolutionStrategy.force`——後者屬 hack） |
| 版本來源 | `backend/gradle/libs.versions.toml` 之 `tomcat`（**版本單一真實來源**，`CSP-006 §2.1`） |
| 範圍 | `backend/build.gradle.kts` 之 `subprojects {}`——★ **產生器模板 `T_ROOT_BUILD` 須同步改動**（`CSP-007`） |

### 3.1 為何用 `constraints` 而非 `force`

Gradle 解析時，**專案層 constraint 與 BOM（platform）constraint 皆參與版本選擇，取最高者**。
11.0.26 > 11.0.24 → 解析為 11.0.26。`force` 會**無條件覆蓋**（含傳遞相依之合理升級），
屬最後手段；本案為「**BOM 落後**」之正常情境，用 constraint 語意正確。

### 3.2 ★ 為何不整包升 Spring Boot

查證 #1 已證 **Spring Boot 4.1.x 僅到 4.1.1**（無含修復之 patch）→ 無「官方對齊」之路可走。
★ **此為 BOM 落後之標準處置**：**只覆寫落後的那一個版本**，不連帶動其他 300 個相依。

---

## 4. 驗證要求（`CSP-006 §5.2` 之 Version Compatibility Gate）

| # | 驗證項 | 通過標準 |
|---:|---|---|
| 1 | **實際解析版本** | `tomcat-embed-*` 三件**皆為 11.0.26**（以 Gradle 實查，非看宣告） |
| 2 | **編譯** | 全庫 `compileJava` ＋ `compileTestJava` 通過 |
| 3 | **全量測試** | 維持 **0 失敗**（基線：194 類別／1096 測） |
| 4 | **執行期啟動** | 服務可啟動、`/actuator/health` 回 200（**編譯過 ≠ 能跑**） |
| 5 | **漏洞歸零** | `tools/scan_deps.py` 之 **CRITICAL 由 3 → 0** |
| 6 | **未破壞其他相依** | 掃描之相依總數不因覆寫而異常增減 |

---

### 4.1 ★★ 驗證結果（2026-10-05；**6 項全數通過**）

| # | 驗證項 | 方法 | 結果 |
|---:|---|---|:--:|
| 1 | **實際解析版本** | Gradle init script 列舉 `runtimeClasspath` | ✅ 三件**皆 11.0.26** |
| 2 | **編譯** | 全庫 `compileJava` ＋ `compileTestJava` | ✅ 通過 |
| 3 | **全量測試** | `./gradlew test`（全庫） | ✅ **1096 測／1 略過／0 失敗／0 錯誤**——**與基線完全一致** |
| 4 | **執行期啟動** | 起 `limit-service` ＋ `/actuator/health` | ✅ **HTTP 200／`status=UP`** |
| 5 | **漏洞歸零** | `tools/scan_deps.py`（OSV） | ✅ **CRITICAL 3 → 0**；**完全無 tomcat 命中**；總命中 18 → 15 |
| 6 | **未破壞其他相依** | 覆寫前後之相依清單 diff | ✅ **286 → 286**；**全清單僅 3 行變動**（即三件 tomcat） |

**★ 決定性證據（非只看宣告）**：產出之 jar 內實際打包
`BOOT-INF/lib/tomcat-embed-{core,el,websocket}-**11.0.26**.jar`（三件齊）。

**剩餘未處理**（`CR-037 §5` 已載）：**Jackson 10 HIGH**（`2.21.5`／`tools.jackson.core 3.1.5`）
＋ **5 MODERATE**（含 `lz4-java`）＋ **前端 1 HIGH／3 MODERATE**。

---

## 5. 已知限制（誠實揭露）

1. **本次只修 Tomcat**——Jackson（**10 HIGH**）與前端（1 HIGH）**未處理**，列 WBS `5.6` 之後續。
2. **11.0.26 之 release notes 未逐條審閱**——採信「同 patch line、無 API 破壞」之通則，
   並以「全量測試 ＋ 服務啟動」實證；**未**做效能回歸。
3. **前端 `npm audit` 之 4 筆未處理**（`vite`／`react-router` 升版屬另一決策）。
4. **覆寫僅作用於本 repo 之複合建置**——`CSP-002 §2` 之 one-service-one-repo 拆分後，
   各倉庫之 `build.gradle.kts` 亦已含同一段（因同源產生）。

---

## 6. 修訂記錄

| 版本 | 日期 | 修訂內容 |
|---|---|---|
| 1.0 | 2026-10-05 | 初版：診斷 3 個 CRITICAL；**查證 6 項**（★ 推翻「升 Spring Boot」之路——4.1.x 無 patch）；裁定覆寫為 **11.0.26**（`constraints` 機制）；訂定 6 項驗證要求；四項已知限制 |
