---
title: 資安掃描修正卡草案（117＋33 條分組）
status: 草案，等決策者裁定。裁完才開 Notion 修正卡。每組一張卡的雛形，含修法方向、驗證方式、建議順序。
relates: [FR-075, FR-076, FR-077, FR-078, FR-079, FR-081, FR-082, FR-083, FR-084, FR-085, FR-086, FR-087, FR-088, FR-095, FR-096, FR-097, FR-098, FR-101, FR-108, FR-109, FR-111]
---

# 修正卡草案：這些問題該分成幾張卡、每張卡修什麼

> **這份文件回答一個問題**：掃描累積下來的 145 條問題，要切成幾張修正卡，每張卡修什麼、怎麼驗、先做哪張。
>
> 這是**草案**，不是已經決定的事。決策者看完裁定之後，才照這份去開 Notion 卡。
> 每一條問題被分進哪一組、有沒有漏掉，看 [分類對照表](classification-matrix.md)；
> 每一條的完整技術細節，看 [總表 §3](README.md)。

---

## 0. 三十秒版

**145 條問題（資安 117 條＋非資安的真程式錯誤 28 條）分成 44 組，建議開 24 張修正卡。**

之所以組數比卡數多，是因為有幾組本來就該合在同一張卡裡修——例如檔案取得鏈那六條，只修其中一條等於沒修。

| | 數量 |
|---|---:|
| 分了幾組 | **44 組** |
| 建議開幾張卡 | **24 張** |
| 未歸組 | **0 條** |
| 已修、不必再排 | **11 條** |
| 改了一半、這一條針對的事還在 | **10 條** |
| 原封不動 | **124 條** |

### 最想請決策者先看這三組

1. **A1 檔案取得鏈（6 條）**——門檻最低的一條攻擊路徑：一個有效帳號加一個檔案編號，就能取走、刪除別家客戶的稽核證據，還能換一張不用登入的下載連結傳到公司外面。**五個出口必須同一張卡一起修**，只修一邊等於沒修。決策者 2026-09-13 已裁「現在就開工單」，這組是那次裁定的直接產物。
2. **C1 設定 API 吐帳密（3 條）**——任何登入帳號打一支查詢就拿到物件儲存的帳號密碼明文。**不修這條，應用層補再多檢查都沒用**：拿到那組帳密可以完全繞過系統直連儲存空間。三處小改。
3. **D2 日誌表本身（7 條）**——密碼原文寫進日誌、日誌表沒有客戶隔離、保存期限從沒生效，三件事疊起來變成「密碼明文無限期累積在一張誰都看得到的表裡」。這組的 `RUN_ENV=prod` 那一半已經修好了（第 25 項），**剩下的部分變得更划算**。

### 三件跟分組有關、決策者可能會問的事

- **「同一種病修一次」到底能省多少**：145 條裡，**光是「只驗登入、不驗這筆資料是不是你的」這一種病就佔了 42 條**（A1～A9 九組）。這九組的修法形狀完全一樣——補一行「這是不是你的」檢查，抄同一個檔案裡寫入方法已經寫好的那支函式。分散開 42 張卡，每張卡的人都要重新理解一次；併成九張，第二張之後都是照抄。
- **修正到現在極度偏食**：兩次複查裡判定「已修」的 11 條，**沒有一條是那九組裡的**——修好的都是資料庫隔離（B 組）與套件小 bug。**資料庫那道牆這段期間補了不少，應用程式那道門一步沒動。** 這不是誰偷懶，是那批工作（FR-094、FR-107）本來就只做資料庫層。
- **有 6 條建議「不開卡」**：X3 那四條複查確認已修好、Z 組裡有兩條總表自己標明「只回報待裁、不直接開卡」。列在這裡是為了讓 145 條每條都有交代，不是要排修。

---

## 1. 怎麼分的、為什麼這樣分

**分組的判準只有一個：這幾條能不能用同一套修法一次解掉。** 不是按套件分、也不是按嚴重度分——按套件分會把同一種病拆散到十幾張卡，按嚴重度分會讓同一條攻擊路徑的頭尾被排進不同輪。

起點是總表 §4 已有的十一組索引（🅰～🅺），**沒有從零發明分法**。本棒做的是三件事：

1. **把 §4 的大組拆細**。§4 的 🅰 組收了 39 條，橫跨七支套件——當成一張卡開，沒有人做得完。本棒依「同一支套件、同一個檔案、同一次測試能驗完」拆成 A1～A9 九組，每組 2～11 條。
2. **回頭核對 §3 全表，把漏分的補進來**。§4 沒收過、本棒新歸入的共 **48 條**——多數是 §3.2 那些非資安的程式錯誤（§4 只零星收了幾條），以及 FR-095／FR-111 後期那幾棒的發現。對照表上每條都標了「本棒新歸入」。
3. **標出狀態**。§4 的索引是逐棒累加的，沒有人回頭核對過哪些已經被別的工作修掉了。本棒依總表自己的兩次複查（09-16、09-20）逐條標記，**已修的 11 條不再排進修正順序**。

**本棒沒有做的事**：沒有開檔重驗任何一條（複查沒覆蓋到的一律照總表寫「仍在」）、沒有改總表一個字、沒有開 Notion 卡。

---

## 2. 建議順序

排序的依據是三件事：**門檻有多低**（要先有什麼才打得到）、**不修會不會讓別的修法失效**、**修法有多確定**（已裁定的、一行就能改的排前面）。

| 輪 | 這一輪做什麼 | 組 | 卡數 | 為什麼排這裡 |
|---:|---|---|---:|---|
| **第一輪** | 堵住「拿到帳密就繞過整個系統」與最低門檻的取檔路徑 | C1、A1 | 2 | C1 不修，後面所有應用層修法都白做；A1 門檻最低且決策者已裁「現在開卡」 |
| **第二輪** | 「只驗登入不驗歸屬」剩下八組一次做完 | A2～A9 | 8 | 修法形狀一樣，第二張之後照抄；同一批人連著做最省 |
| **第三輪** | 日誌這條線 ＋ 憑證處置 | D1～D5、C2、C4 | 5 | 密碼外洩的完整鏈路，要一起收才算修完 |
| **第四輪** | 輸入不驗、資源耗盡、防竄改 | K1～K5、R1～R3、T1 | 4 | 彼此獨立，可以平行派 |
| **第五輪** | 資料庫隔離收尾 ＋ 小修合卡 | B1～B3、X1、X2 | 4 | B 組大半已被 FR-094 修掉，剩收尾；X 組是順手做掉的小東西 |
| **待裁** | 要先定產品方向才能動程式 | P1～P7、I1、I2 | （1 張決策卡） | 修法不只一種選項，程式不能先動 |

**跨輪的一條線**：C 組（憑證）裡有幾條是「去後台按撤銷／換密碼」的動作，不是寫程式。那幾條不占開發時間，**可以跟第一輪平行做**。

---

## 3. 各組草案

每一組的格式固定：**共同病根一句 → 涵蓋哪幾條 → 修法 → 怎麼驗 → 風險級別**。
「涵蓋哪幾條」欄裡，編號後的括號標的是狀態；沒標的就是「仍在」。

---

### 🔴 A 系列：只驗登入、不驗這筆資料是不是你的（九組 42 條）

**整個 A 系列的共同病根**：系統認得出「你是誰」，但從來不問「這筆資料是不是你的」。登入就放行。

**九組共用同一套修法**：在服務層補一道「這筆資料的主人是不是呼叫者（或呼叫者是不是這個專案的成員／管理者）」的檢查——**每一組要抄的那支函式，都已經寫在同一個檔案的寫入方法裡**。這不是設計新機制，是把已經存在的檢查補到漏掉的地方。

🔴 **這一系列有一個驗收陷阱，每一組都適用**：總表複查兩次都撞到「端點換上了看起來像守門的裝飾器，但那道守門從來不是歸屬檢查」（第 34、45、74 項）。**驗收時不能只問「有沒有補守門」，要打開那道守門的實作看它到底檢查什麼。**

#### A1 檔案取得鏈（6 條 · 建議開 1 張卡 · 🔴 最高優先）

**病根**：檔案的下載、換發免登入連結、刪除、服務層取檔，四個出口全都只驗登入。

| 條 | 是什麼 | 狀態 |
|---|---|---|
| 34 | 下載端點只驗登入 | 部分修（資料庫層已補、應用層沒動） |
| 35 | 換發不用登入就能下載的通行證，不驗歸屬 | 仍在 |
| 37 | 刪除任何檔案不驗歸屬 | 仍在 |
| 40 | 主專案側檔案服務層三個方法都只憑編號取檔 | 部分修（同 34） |
| 45 | 任務詳細 API 收了專案編號卻沒拿來用 | 部分修 |
| 47 | 存放檔案的資料表沒有隔離（最後一道防線） | 部分修（資料庫層已補） |

**涵蓋範圍**：2 支套件（jedi-file-upload、主專案側）＋ 5 個檔案。

**修法**（四步，第三步要決策者放行）：
1. **服務層補歸屬檢查**（`managed_file_upload_service.py` 的取檔／轉檔／刪檔三個方法）——這一層是唯一「已經把檔案撈出來、知道它屬於誰」的地方，**真正該補的是這裡**。
2. **換發通行證的入口補檢查**——簽發前先確認這個檔案是不是呼叫者的；並讓通行證綁客戶與使用者，不只綁檔案。
3. **出貨基線同步**（要決策者裁）：資料庫那兩欄與隔離規則目前靠 installer 事後補，基線建表還是舊形狀。**重產基線要寫 188 基線庫，屬決策者裁示。**
4. **第 45 項分開寫**：它剩的三個缺口跟其餘五條不同（查詢那支完全沒補、補的兩支不核對任務歸屬、資料層更新只憑編號查），**開卡時要分段寫清楚**，不能寫成「同上」。

⚠️ **34／40／47 三條的原文必須改寫再開卡**——原文說「資料表沒有客戶歸屬欄位、隔離是關的」已經過期（FR-107 為了別的目的補上了）。照抄會讓接手的人去做一件已經做完的事，然後以為整條修完了。

**怎麼驗**：用 A 客戶的帳號，拿 B 客戶的檔案編號打下載、換通行證、刪除三支，都要回 403（現在是成功）。同租戶內跨專案也要擋。DEV 唯讀可以先查資料庫現況，實際打端點要在 DEV 做。

**風險級別**：🔴 高（組內最高：34／35／40／47 四條高風險）

---

#### A2 稽核流程讀取（5 條 · 建議開 1 張卡）

**病根**：稽核流程引擎裡，同一個檔案的寫入方法都有歸屬檢查，讀取方法全部漏掉。

| 條 | 是什麼 |
|---|---|
| 49 | 讀證明清單只驗登入（拿到檔案編號後可接 A1 直接下載檔案本體） |
| 50 | 讀單筆證明沒有歸屬檢查（目前被另一個程式錯誤擋住，那個錯誤一修就真外洩） |
| 51 | 流程留言讀寫都只驗登入（可冒充同事名義發言釣魚） |
| 52 | 讀稽核階段歷程完全沒有權限檢查 |
| 53 | 讀階段資訊：用專案編號查角色、用另一個輪次編號撈資料，兩者不核對 |

**涵蓋範圍**：jedi-flow-engine ＋ 主專案側 · 4 個檔案。

**修法**：
1. 49／50 在同一個檔案補兩行，抄同檔已有的 `assert_project_participant`。
2. 51 要在另一個模組補讀取與寫入兩處。**決策者 2026-09-13 已裁升為高風險。**
3. 53 要一併補 `advance_stage`／`rollback_stage` 兩支的輪次歸屬比對——**目前跨專案寫入是靠下游套件的第二道檢查在擋，這一層自己沒檢查**。不補的話，將來新增一支不走那個套件的處理函式，洞就重新打開。
4. **50 與那個程式錯誤必須同一張卡**：單筆查詢的端點誤用了「多筆」的序列化方式，先出錯所以沒真外洩。**只修程式錯誤不補權限，等於親手把洞打開。**

**怎麼驗**：A 客戶帳號拿 B 客戶的任務編號／輪次編號打這五支，全部要 403。第 50 項要在修完序列化錯誤之後再驗一次。

**風險級別**：🔴 高（49／51 兩條高風險）

---

#### A3 任務平台名冊與指派（11 條 · 建議開 1 張卡）

**病根**：成員名冊與任務指派的讀取全部沒有權限檢查，而且查詢條件全是選填——**送一個空請求就回整張表**（實測：成員名冊 751 筆、任務指派 12,494 筆，跨所有客戶）。

| 條 | 是什麼 |
|---|---|
| 60 | 專案層成員名冊讀取無檢查、空請求回全表（**這是整組的資料源頭**） |
| 61 | 控制項層成員名冊兩支同樣無檢查 |
| 62 | 第六支成員服務整個檔案零權限檢查（目前沒有 API 入口，接上就開） |
| 63 | 流程參與者的兜底檢查寫在提前返回之後，永遠執行不到 |
| 64 | 寫入時不驗 `group_id`／`control_id` 是不是真的屬於這個專案 |
| 68 | 任務指派清單只驗登入、八個條件全選填 |
| 69 | 新增指派用自填的專案編號判管理者，不驗任務歸屬 |
| 71 | 更新指派撈不到紀錄時整段跳過管理者檢查 |
| §3.2 17 | 三支服務的「用編號查資料」永遠回空——**補完權限拿這條路測會得到假通過** |
| §3.2 19 | 流程參與者表 DEV 0 筆、改刪必出錯（就是第 63 項造成的） |
| §3.2 20 | 專案啟動時的成員同步刻意繞過套件守門（設計自陳，記錄不判） |

**涵蓋範圍**：jedi-task-platform ＋ 主專案側 · 約 10 個檔案。

**修法**：
1. 讀取那幾支照抄同檔已有的 `delete_task_assignee` 寫法補檢查，**專案編號改必填**。
2. 63 把兜底檢查移到提前返回之前，並補上那個根本不存在的驗證方法（或改呼叫真的存在的那支）。
3. **§3.2 第 17 項必須同卡先修**——那支永遠回空的查詢會讓「補完權限後的測試」看起來通過，實際上只是查不到東西。**不修它，這張卡的驗收是假的。**
4. 62 目前沒有 API 入口，**優先度低於同組其他條**，但要一起補，否則哪天有人接上就是一個全開的入口。

**與 I2 的關係**：60／61／68 的「空請求回全表」根因在共用底層（I2 第 70 項）。決策者 2026-09-15 已裁「要在底層擋，但分兩步，第一步先盤點」。**這張卡走的是第二條路——逐支補「專案編號必填＋成員檢查」，不等底層改**；底層那件事照原裁定另案進行。

**怎麼驗**：送空白請求給那幾支，要回 400（欄位必填）而不是整張表；帶別人的專案編號要回 403。**驗之前先確認 §3.2 第 17 項已修**，否則結果不算數。

**風險級別**：🔴 高（60／69 兩條高風險）

---

#### A4 問卷讀取與討論（8 條 · 建議開 1 張卡）

**病根**：這是整個掃描計畫裡「補權限只補了一半」最乾淨的一次實證——填答功能 14 個入口，**6 個寫入全部有檢查（6/6），8 個讀取一個都沒有（0/8）**，而且在同一個服務檔案裡。

| 條 | 是什麼 |
|---|---|
| 89 | 查填答歷史明細，空請求整包讀走全客戶所有問卷的每一版答案與審核意見 |
| 90 | 讀某份任務問卷的答案不檢查是不是你的 |
| 91 | 列出任務問卷不限範圍（同時是第 90 項的入場券） |
| 92 | 列出填答歷史不限範圍 |
| 94 | 還原歷史版本不檢查那個版本是不是這份問卷的 |
| 95 | 即時同步的房間想進哪間就進哪間 |
| 96 | 問卷討論列表送空查詢就撈回全公司討論 |
| 97 | 改／刪討論不驗是不是本人寫的，改完還掛原作者名字 |

**涵蓋範圍**：jedi-survey · 約 8 個檔案。

**修法**：套件裡**已經有現成的 `assert_task_survey_writer` 與對應的讀取守門**，逐支掛上即可；91／92／96 三支的查詢條件改必填。97 若產品面決定「管理員可以刪別人的留言」，要走一條寫明白的管理路徑，**照樣檢查他是不是這個專案的人**。

**這一組要帶一句寫進卡片**：2026-07 那次統一補權限的工作只涵蓋了寫入。**往後任何一次補權限的驗收，都要把讀取入口分開數一遍。**

**怎麼驗**：A 部門帳號拿 B 部門的問卷編號打這八支，全部 403；空請求要 400。即時同步那兩支要另外開連線測。

**風險級別**：🔴 高（89／90 兩條高風險）

---

#### A5 主專案專案讀取（2 條 · 併入 A3 或獨立小卡）

| 條 | 是什麼 |
|---|---|
| 65 | 專案摘要報告清單與歷史版本四支讀取只驗登入（含稽核結論全文） |
| 66 | 稽核輪次選單一支只驗登入 |

**修法**：照抄同檔已有的 `assert_project_participant`，一行。跨客戶已被 FR-094 的資料庫隔離接住，**現在只剩同客戶內跨專案**。

**風險級別**：中。**建議併入 A3 同一棒做**（同一個人手上，抄的是同一支函式）。

---

#### A6 弱點掃描端點（3 條 · 建議開 1 張卡）

| 條 | 是什麼 |
|---|---|
| 85 | 「測試連線」不驗權限——按一下就把掃描工具帳密解密送到按的人指定的主機（🔴 高） |
| 86 | 同一支端點，目標主機由呼叫者指定、不比對白名單——代理程式變成任意連線跳板 |
| 88 | 查掃描執行紀錄少了專案參與者檢查（同服務另外八支都有做） |

**修法**：85 掛上同檔其他三支在用的「工具設定修改」權限點；86 目標主機限制成存好的設定範圍；88 補一行參與者檢查。

⚠️ **85 與 86 必須同卡**：補了權限（85）不會讓 86 消失，只是把門檻從「任何登入者」提高到「工具管理員」。**只修 85 就結案，是把一個對外的跳板留給內部人。**

**風險級別**：🔴 高。

---

#### A7 舊 Drive 分類線（3 條 · 🔴 要先裁「刪路由還是補守門」）

| 條 | 是什麼 |
|---|---|
| 108 | 預覽任意 Google 雲端硬碟檔（🔴 高，本 arc 唯一高風險） |
| 109 | 查結果、查報表不驗專案成員 |
| 111 | job 列表／單一狀態不驗專案，且進度登記簿是全程序共用、不分客戶 |

**這組要先裁一件事**（總表 §7 第 19 項）：舊線已標 legacy、**前端入口已經拿掉**，後端三支路由仍掛著。**刪那三支路由一次消掉這三條**；留著就要三條各補守門。

**建議**：先刪路由。理由是前端已經沒有入口，留著的三支路由是純風險、零價值；補守門要寫的程式比刪路由多，而且補完還是沒人用。

**風險級別**：🔴 高（108）。**但如果裁定刪路由，這張卡會縮成一個 10 分鐘的工作。**

---

#### A8 公告與 AI 儀表板（2 條 · 建議開 1 張卡）

| 條 | 是什麼 |
|---|---|
| 1 | 公告四個漏洞（AI 儀表板繞權限讀全租戶公告含草稿／改刪不驗歸屬／單筆讀取零檢查／無部門帳號全放行） |
| 8 | AI 儀表板讓任何登入帳號列出全公司帳號、角色、租戶、部門清單 |

**修法**：公告那四個有現成的檔名行號可以直接抄。第 8 項的正規做法是讓 AI 儀表板申報的每支查詢各自標明需要什麼權限，**最快的止血是把那四支查詢從 AI 可用清單移除**。

⚠️ **這組跟 P6（第 10 項「視同管理員」後門）同在 AI 儀表板上**，但那條是刻意設計、要先裁產品方向，**不要一起修**。

**風險級別**：中。

---

#### A9 能力點宣告了但沒接線（2 條 · 建議開 1 張卡）

| 條 | 是什麼 |
|---|---|
| 58 | 流程範本列表與單筆讀取沒掛「讀取流程範本」能力點（能力點存在、選單也綁了，就是 API 沒掛） |
| 113 | `detection-profile.read` 資料庫早宣告、前端矩陣也認，後端七支讀取一支都沒檢查 |

**病根跟 A1～A8 不同**：那些是「忘了寫檢查」，這兩條是「**權限點宣告好了，後端沒接上去**」——結果是租戶管理員以為拿掉權限就讀不到，實際上 API 完全敞開。

**修法**：各補一行掛上既有能力點。

**要帶進卡片的一句**：這種病跟 P3（第 80 項資產清冊）長得很像，**但性質相反**——P3 是程式碼契約自己寫明「讀取不守」的刻意取捨，這兩條是漏接。**不要一起處理。**

**風險級別**：中。

---

### 🅱 B 系列：資料庫隔離（三組 12 條）

#### B1 開關沒開／規則沒訂完（4 條 · 建議開 1 張卡，**大半已修**）

| 條 | 是什麼 | 狀態 |
|---|---|---|
| 43 | 13 張表隔離沒生效（實測曾看到 39 筆待辦、213 筆專案） | 部分修（甲乙丙戊四組已由 FR-094 全部開完） |
| 44 | 4 個畫面直接繞過隔離 | 已修 |
| 5 | 三張表訂了規則但開關沒開 | 已修 |
| 4 | 公告與部門關聯表沒訂規則 | 仍在 |

**現況**：這組**實質上只剩兩條**。第 43 項只剩一張 `config.log_forwarding_settings` 沒處理，而那張正是報告自己標「建議重新分類、不算隔離缺口」的、且牽涉 P2（第 75 項）。

**修法**：第 4 項走 sql-migration 標準流程。⚠️ **開卡時務必寫明**：`bulletin_org_units` 只有兩個欄位、**沒有客戶歸屬欄位**，不能照抄母表 `bulletins` 的四條規則——要嘛透過母表借隔離，要嘛先加欄位。**不寫這句，接手的人幾乎一定會照抄然後失敗。**

**風險級別**：低（剩下的部分）。**建議降到第五輪收尾做。**

---

#### B2 連歸屬欄位都沒有（7 條 · 建議開 1 張卡 · ⚠️ 難度跟 B1 完全不同）

| 條 | 哪些表 |
|---|---|
| 23 | `system_logs`（668,813 筆）與 `api_logs` 兩張日誌表 |
| 7 | jedi-issue 五張表（問題單、成員、三張關聯表） |
| 47 | 檔案表（✅ 資料庫層已修） |
| 67 | `oscal.profile_imports`／`ssp_implemented_requirements` |
| §3.2 22 | 任務指派的驗證觸發器沒真的建起來，而且它讀的三個欄位在表上不存在 |
| §3.2 31 | 基準的領域層與存取層四個檔零隔離程式碼（**前提記錄，不是要改的錯**） |
| §3.2 32 | `detection_profile_controls` 零隔離全靠約定（**脆弱設計記錄**） |

⚠️ **這組不能跟 B1 排同一輪**。B1 是「開關打開」，這組是「**先改資料表結構、回填既有資料、再補規則**」——而且 `system_logs` 那張有 66 萬筆要回填。

**修法**：每張表都是「加欄位 → 回填 → 開隔離 → 補規則 → 出貨基線同步」五步。**建議一張表一張卡，不要併成一張大卡。**

**要先裁的**（總表 §7 第 8 項）：兩張日誌表**到底要不要做客戶隔離**，還是明確定位成「只給內部維運看的全域資料」、改成限縮誰能查就好？後者不用改表結構，成本差一個數量級。**這件事沒裁，B2 這組動不了。**

**§3.2 第 31、32 項不開卡**——總表自己標明是「前提記錄」與「脆弱設計記錄」，不是程式錯誤。**建議寫進資料庫設計文件，讓下一個改動的人知道這裡的安全是靠什麼撐著。**

**風險級別**：🔴 高，但**被「要先裁方向」擋住**。

---

#### B3 隔離規則方向寫反（1 條 · 建議開 1 張卡）

**第 87 項**：把組織路徑 `/1/102/` 切成 `[1, 102]` 當白名單，結果**子單位看得到母單位的資料（還能改能刪），母單位反而看不到自己底下子單位的**。該擋的沒擋、不該擋的擋了。

**這條最不容易被發現**，因為從外面看「隔離有開」。DEV 實查確認母子結構真的存在、資料全在子單位，**兩面都已經在發作**。

**涵蓋範圍**：**9 張表跨三個套件**（jedi-detection 5 張＋遠端代理程式 `agent_tasks` ＋三張授權表）＋出貨基線。

**修法**：改判斷式即可，但**要一次改 9 條、且動到出貨基線**（屬決策者裁示）。

**風險級別**：中，但**這是資安與功能雙錯**——母單位看不到子單位的資料是個功能 bug，客戶會直接回報。

---

### 🅲 C 系列：憑證（五組 14 條）

#### C1 設定 API 吐帳密（3 條 · 建議開 1 張卡 · 🔴 最高優先之一）

| 條 | 是什麼 |
|---|---|
| 39 | 任何登入帳號打一支查詢就拿到自己客戶的雲端儲存位址、帳號、密碼明文（三層防護一起破） |
| 72 | 讀取系統設定的三個入口只驗登入（同檔寫入四個入口每個都有檢查） |
| 73 | 密碼遮罩名單漏掉物件儲存那一組 |

🔴 **這三條必須同一張卡**。只補權限（72）不補遮罩（73），有正當權限的管理員打開頁面時瀏覽器仍會收到共用密鑰明文——任何看得到他瀏覽器流量、存檔或前端錯誤日誌的人都拿得到。**只修一邊等於沒修乾淨。**

**修法**：
1. 三個讀取入口掛上同檔寫入已經在用的權限檢查。
2. 遮罩的兩份名單各補一處（群組名單補「儲存設定」、欄位名單補物件儲存實際用的欄位名）。
3. ⚠️ **動的是標註「凍結」的契約，要連測試一起改。**

**為什麼排最前面**：**不修這條，應用層補再多檢查都沒用**——拿到那組帳密可以完全繞過整個系統直連儲存空間。

**怎麼驗**：用一個零權限的登入帳號打那三支查詢，回應裡不能出現任何密碼欄位；用有權限的帳號打，密碼欄位也要是遮罩後的值。

**風險級別**：🔴 高。

---

#### C2 憑證已經外流，要換要清（4 條 · 建議開 1 張卡，但**多數是動作不是程式**）

| 條 | 是什麼 | 性質 |
|---|---|---|
| 2 | 資料庫密碼、四家 AI 服務金鑰、Nexus 與 MinIO 憑證寫進版控 | 換憑證 |
| 3 | 安裝程式每套部署種同一組原廠超管密碼 | 出貨預設值（見 P7） |
| 83 | jedi-issue 歷史裡第二把 GitLab 權杖，**從沒被撤銷過** | 🔴 去後台按撤銷 |
| 84 | `cmmgr` 密碼＋兩組產品帳密寫在需求文件裡，**那份文件已經發佈到公開網站** | 🔴 換密碼＋清檔 |

🔴 **第 83、84 兩項不是「要不要修」的問題，是一個動作**。83 是去 gitlab.com 後台按撤銷（並查該帳號從 2025-04 起的稽核紀錄）；84 是換密碼並把公開站上那頁清掉。**這兩件不占開發時間，可以跟第一輪平行做。**

⚠️ **決策者 2026-09-19 已裁「三個例外也不先做」**（含第 84 項）——理由是快掃完了、不分批。**掃描現在已經收口，這條裁定的前提消失了**，建議請決策者重新確認 83／84 要不要立刻處理。

**已裁定不必再問的**：測試機專用的資料庫與管理帳號密碼**不需更換**；**不重寫 git 歷史**。

**風險級別**：🔴 高（84：不用登入就取得、且是繞隔離的帳號）。

---

#### C3 預設不安全（4 條 · 併入 X1 小修合卡）

| 條 | 修什麼 |
|---|---|
| 19 | 主產品連 Redis 寫死不驗憑證——**另一個套件已經修好的同一個漏洞的複製品**，照抄現成修法＋現成測試 |
| 29 | 忘記密碼的信箱遮罩，套件預設改成開啟（主專案已覆寫，但套件預設不安全） |
| 42 | 連物件儲存預設改成開加密 |
| 117 | 建掃描基準時放行明文 `http://`，且網址型來源不記指紋 |

**四條都是一行改預設值**。建議**併進 X1 一起做**，不單獨開卡。

**風險級別**：中（19 最高，因為是已知修法的漏網複製品）。

---

#### C4 憑證落地留存（2 條 · 建議開 1 張卡）

| 條 | 是什麼 |
|---|---|
| 107 | 派工時把解密後的客戶機房登入帳密**另存一份明文**進工單表——那份從頭到尾沒有任何程式讀過，而且沒有清理機制、累積無上限 |
| 103 | AI 金鑰走 `docker run` 命令列，同機任何帳號 `ps` 看得到（落地版跑不到） |

**修法**：107 刪掉寫入那一行 ＋ 補一支清存量的 migration。103 改 `--env-file` 或 `-e KEY` 不帶值。

**107 值得單獨強調**：產品刻意做的加密保護被這一行繞過了——拿到資料庫備份、`pg_dump` 檔或唯讀帳號的人，**一句 SQL 就得到客戶正式機房的可用 SSH 密碼**。而且那份資料沒有任何人在用。**刪掉它沒有任何副作用。**

**風險級別**：中，但 107 的**投入產出比極高**（刪一行 ＋ 一支 migration）。

---

#### C5 三環境共用公鑰（1 條 · 不開卡，等 LC）

**第 6 項**：開發環境的私鑰簽出來的授權檔，正式環境的驗證也會通過。三個環境的公鑰全部編譯進同一份後端程式。

**決策者已裁**：現階段不處理，**等正式簽發站建好之後一併處理**。程式檔頭註解說明這是刻意設計（為了支援日後換發新公鑰不中斷）。

**這一條列在這裡只為了「每條都有交代」，不建議現在開卡。**

---

### 🅳 D 系列：日誌與外送（五組 17 條）

#### D1 密碼原文進日誌（3 條 · 建議開 1 張卡）

| 條 | 是什麼 | 狀態 |
|---|---|---|
| 22 | 登入密碼與憑證原文直接寫進日誌檔與資料庫 | ✅ 已修（09-20 複查：四個 log 檔實際 grep，明文 0 筆） |
| 30 | 全站唯一那道遮罩機制，遇到含引號的密碼只遮一半 | 仍在 |
| 18 | 竄改回報把伺服器日誌最後 50 行原文送到原廠 | 仍在 |

**第 22 項雖然已修，但留下兩件殘留**，建議寫進這張卡：
1. 2026-09-17 之前的**舊 log 檔輪轉後可能仍有明文**——屬資料清理，不是程式問題。
2. 遮罩比對的是 JSON 的 key 名，**表單編碼的請求擋不到**（登入走 JSON 已實測有遮）。

**第 30 項的修法**（總表 §7 第 7 項已寫明方向）：改成先把內容解析成結構化格式再逐層遮蔽。**這會動到全站唯一的這道遮罩機制，屬核心共用邏輯——依測試政策，這一條要補寫測試。**

**風險級別**：中（22 已修後）。

---

#### D2 日誌表本身（7 條 · 建議開 1 張卡 · ⚠️ 與 B2 相依）

| 條 | 是什麼 | 狀態 |
|---|---|---|
| 23 | `system_logs` 沒隔離、也沒有可用來隔離的欄位（668,813 筆） | 仍在（同 B2） |
| 24 | 完整錯誤堆疊寫進那張沒隔離的表 | 部分修（**風險反而被放大**） |
| 25 | 出貨設定沒標「這是正式環境」 | ✅ 已修 |
| 26 | 監控功能載入就執行 | ✅ 已修 |
| 27 | 兩種日誌類別在正式環境寫死最詳細等級 | 部分修（改掉一項，剩兩棵仍寫死 DEBUG） |
| 79 | 兩張日誌表的保存期限從未生效 | ✅ 已修（已接上每日 03:30 排程） |
| §3.2 11 | 寫資料庫日誌失敗會連帶弄壞使用者的請求 | 部分修（**風險反而被放大**） |

🔴 **這組有一個要特別講清楚的**：第 24 項與 §3.2 第 11 項在這段期間**風險反而變大了**。同一支改動（CM-1920）把資料庫日誌處理器補掛到正式與測試環境——它修的是「寫多少」，而「寫失敗會弄壞使用者請求」「錯誤堆疊落在沒隔離的表」這兩件事沒碰，等於**原本只在開發機的問題，現在正式環境也會走到**。

**修法**：
1. §3.2 第 11 項：那支 `emit()` 全函式還是沒有錯誤處理，**補上 try/except**，一個小改。
2. 第 24 項：只保留錯誤的類型與訊息、不保留完整堆疊。
3. 第 27 項剩下的：把 `sqlalchemy.orm` 與 `pymongo.event_loggers` 兩棵調回 WARNING。
4. 第 23 項要等 B2 那個產品決策。

**好消息**：這組七條裡三條已修，剩下的四條**都是小改**（一個 try/except、一個不存堆疊、兩個調等級）。**投入產出比很高。**

**風險級別**：中。

---

#### D3 日誌轉送鏈（3 條 · 建議開 1 張卡 · ⚠️ 與 P2 同一個決策）

**這三條合起來是一條完整攻擊鏈**：

| 條 | 是什麼 |
|---|---|
| 75 | 客戶的管理員改得動「全公司日誌要送去哪」（🔴 高） |
| 76 | 路上完全沒加密、不必解密就看得到 |
| 77 | 還能在裡面塞偽造紀錄混淆追查 |

**與 D1 第 22 項直接相扣**——日誌裡有密碼原文，所以這條管道外洩的就是密碼本身。

**第 75 項要先裁產品方向**（見 P2），**76／77 不用等**：76 補加密選項、77 過濾換行符號（gelf 那半已經有現成作法可抄），兩條都可以現在做。

**建議**：**這張卡拆成兩段**——76／77 現在做，75 等 P2 裁完再接上。

**風險級別**：🔴 高（75）。

---

#### D4 匯出公式注入（2 條 · 併入 X1 或獨立小卡）

| 條 | 是什麼 |
|---|---|
| 78 | 匯出操作記錄的 Excel 沒過濾公式字元——**種下去不需要任何權限**，在任何權限檢查跑之前就記下來了（🔴 高） |
| 82 | 匯出意見回饋的 Excel／CSV 同一種病 |

**修法**：兩處共用一支「開頭是公式字元就前置單引號」的中和函式。**同一種病兩個位置，一次修完。**

**風險級別**：🔴 高（78：不用登入就能種，唯一門檻是等管理員自己打開檔案）。**但修法只有一支小函式**——建議**提前到第一輪順手做掉**，不要排到第三輪。

---

#### D5 錯誤原文回前端（2 條 · 併入 X1）

| 條 | 是什麼 |
|---|---|
| 100 | 問卷資料夾列表把資料庫原始錯誤訊息整句吐回前端（含表名、欄位名、SQL 片段） |
| §3.2 25 | 證據分類失敗時把上游例外原文存進批次、前端可讀 |

**修法**：100 把那段「所有例外都接住」的程式拿掉，讓框架的錯誤處理器回標準錯誤碼；§3.2 25 改存固定錯誤碼＋一句白話，原文只進 log。

**風險級別**：低。

---

### 🅴 E1 回應夾帶內部欄位（3 條 · 建議開 1 張卡）

| 條 | 是什麼 |
|---|---|
| 9 | AI 儀表板查詢結果夾帶密碼加密用的鹽值 |
| 12 | AI 儀表板回應夾帶鹽值與「是不是超級管理員」旗標 |
| 33 | **套件共用的序列化工具原樣吐出整個物件、零欄位過濾**（上面兩條只是它造成的個案） |

🔴 **修第 33 條才是治本**，只修 9／12 這兩個個案，之後還會有新的個案冒出來。

**修法**：在套件層的序列化工具加白名單或黑名單參數（至少擋掉密碼、鹽值、憑證這類欄位名）；9／12 同時加欄位白名單或重用既有查詢已經寫好的排除設定。

⚠️ **33 在 jedi-common，改了要發版才生效**，節奏跟只改主專案不同。

**風險級別**：中。

---

### 🅺 K 系列：外部送什麼就收什麼（五組 10 條）

#### K1 `apply=False` 大量指派（2 條 · 建議開 1 張卡）

| 條 | 是什麼 |
|---|---|
| 98 | 資料夾更新塞一個「已刪除」欄位就繞過「非空資料夾不可刪」守門，造出孤兒資料 |
| 99 | 資料夾列表蓋掉內部的「排除系統資料夾」開關，叫得出快照與已刪除的資料夾 |

**病根**：網址入口那行負責「檢查前端送來的欄位對不對」的宣告被加了 `apply=False`——**叫框架完全跳過驗證，那一行只剩裝飾作用**。業界叫「大量指派」。

**修法**：拿掉 `apply=False`，明確宣告允許的欄位。⚠️ **同樣寫法在問卷套件的四個網址入口上都有，四個一起改，不要只修被掃到的那兩支。**

🔴 **這張卡要附帶一件盤點工作**（總表 §5 已列）：**另外 20 支套件要搜一遍有沒有同樣寫法**。這件事**比修這兩條更有價值**——`apply=False` 是一個可以用一行 grep 找遍全公司的形狀。

**風險級別**：中。

---

#### K2 檔名／副檔名不驗（2 條 · 建議開 1 張卡）

| 條 | 是什麼 |
|---|---|
| 36 | 上傳的網頁檔在我們自己的網域裡被當程式執行（儲存型 XSS），副檔名完全不限制（🔴 高） |
| 101 | 代理程式自報的檔名原樣存成證據檔，稽核人員預覽時 `.html` 會在瀏覽器裡執行 |

**同一種病的兩個入口**：一個是使用者上傳、一個是代理程式回報，**但落地點是同一支預覽端點**（依副檔名決定型別、而且是直接在瀏覽器裡開不是下載）。

**修法**：預覽端點改成不依使用者自填的副檔名決定型別、危險型別一律強制下載；上傳與回報兩側都補副檔名白名單、去掉路徑。

**風險級別**：🔴 高（36）。

---

#### K3 規則包不驗內容（3 條 · 建議開 1 張卡）

| 條 | 是什麼 |
|---|---|
| 115 | 上傳的掃描規則包原封交給外部工具，**那工具會把裡面的設定檔當 Ruby 樣板先執行再解析**（🔴 高） |
| 112 | 「最多一萬個檔」的上限對 `.zip` 形同虛設（打開那一刻就整份展開進記憶體） |
| 116 | 網址型規則來源**完全繞過**壓縮檔驗證器（三道上限只接在上傳分支） |

**112 與 116 是同一支驗證器的兩種病**：112 是「上限存在但太晚生效」，116 是「上限根本沒接進這條路」。**一起修。**

**修法**：115 改成解析前先剝掉或轉義樣板語法（或換一個不執行樣板的解析方式）；112 改成逐筆讀；116 把驗證器接到網址分支的呼叫點。

**風險級別**：🔴 高（115）。

---

#### K4 字串拼查詢（2 條 · 建議開 1 張卡）

| 條 | 是什麼 |
|---|---|
| 21 | 資料庫隔離用的連線變數用字串拼接組進 SQL（三位檢查員一致認為**目前不可被利用**） |
| 110 | 查 Google 雲端硬碟的搜尋條件字串拼接、沒跳脫（未實測） |

**這組記的是「寫法本身不安全」，不是「現在就有漏洞」**。擋住第 21 項的是外部環境的巧合（值的來源剛好是整數主鍵與資料庫查出來的字串），**不是寫法本身安全**。

**建議**：**趁現在改掉，不要指望以後有人會一直記得這個限制。** 改成參數綁定，成本很小。

**風險級別**：低（但形狀不好）。

---

#### K5 換工具不重驗上限（1 條 · 併入 A6 或獨立）

**第 105 項**：在一張稽核任務上換掃描工具時，「要掃哪些機器」不會拿實際生效的值重新檢查台數上限——先綁一支不設上限的工具、填一個超大網段，再換工具，舊的超大網段跟著留到新工具底下，執行時逐台展開吃爆記憶體。

**修法**：換工具時用實際生效的值重跑一次上限檢查。

**建議併入 A6**（同一支套件、同一批人）。

---

### 🅵 T1 防竄改機制（6 條 · 建議開 1 張卡 · 自成一組）

**這組跟其他組的修法完全不互相影響**，可以任何時候獨立排。

| 條 | 是什麼 |
|---|---|
| 13 | **換掉驗證簽章的函式庫，整套機制永久失效**——已實測證實（🔴 高） |
| 14 | 文件宣稱兩道鎖，程式只做了一道，刪一個檔就能讓鎖定的機器重開（🔴 高） |
| 15 | 環境變數可以換掉「要核對哪個目錄」（**這是 13 的放大器**，單獨修意義不大） |
| 16 | 解鎖紀錄毀損時預設當作「一張都沒用過」 |
| 17 | 鎖定畫面洩漏機器指紋與事件編號 |
| 18 | 回報功能夾帶日誌內容（同 D1） |

**要先裁的兩件**（總表 §7 第 9、10 項）：
- 第 13 項**要不要開卡**——已實測、風險維持高，三個候選修法已寫在總表，等決策者選一個。
- 第 14 項**選哪個修法方向**——補開機時的資料庫查詢／補同步機制反向寫回／只改文件讓它與實際行為一致。**三個選項成本差很多。**

⚠️ **15 必須跟 13 同一張卡**，單獨修沒有意義。

**這組還有三個相鄰面向從頭到尾沒碰過**（總表 §3.4）：解鎖檔的簽發端（在 License Center）、驗章的加密邏輯本身、打包出貨時產生清單檔的流程——**最後這件直接決定防竄改實際保護的範圍有多大**。建議寫進卡片當已知缺口。

**風險級別**：🔴 高。

---

### 🅹 R 系列：一個帳號就能讓系統對所有人不回應（兩組 8 條）

#### R1 BPMN 輸入炸彈（4 條 · 建議開 1 張卡）

| 條 | 是什麼 |
|---|---|
| 55 | 惡意流程圖卡死處理執行緒（🔴 高，決策者 09-13 裁升級） |
| 56 | 一筆空字串範本讓所有人的清單頁出錯、不會自己恢復 |
| 57 | 「檢查流程圖」API 任何登入帳號打一次卡住 120 秒、連打四次全站不回應（🔴 高，同裁定） |
| §3.2 15 | 相關的一條路徑（已隨 v1 殘留端點清理順手消失） |

**55／56／57 是同一個根本原因**（不信任使用者送進來的 XML），總表已建議合成一張「BPMN 輸入強化檢查」的卡。

**修法分三段**：
1. **先止血**：57 補上功能權限檢查與長度上限兩行，把門檻從「任何登入帳號」拉高。
2. **治本**：驗證邏輯改用字典結構、加節點數量上限。
3. **寫入端**：補驗證會動到主專案側的 `module_frame_item_route.py`，**跨程式庫的修改要注意**。

**風險級別**：🔴 高。

---

#### R3 其他資源上限（4 條 · 建議開 1 張卡）

| 條 | 是什麼 |
|---|---|
| 31 | 分頁「一頁幾筆」沒有上限（**全站共用底層**，兩支路徑都撞到過） |
| 38 | 上傳沒有單檔大小與檔案數量上限 |
| 104 | 分類容器無記憶體／CPU／處理程序上限，逾時殺不掉容器（落地版跑不到） |
| 114 | 手動重新掃描無條件開背景執行緒，連打幾百次就是幾百條執行緒 |

**第 31 項最划算**：改一個共用底層的預設上限，**全站所有分頁一次受保護**。而且它不會被既有的「請求大小上限」擋住——攻擊形狀是「請求很小、要求回傳的資料很大」。

**第 114 項修法極便宜**：服務裡**早就有 `running` 狀態且有在寫入**，只是沒人拿來判斷。

**風險級別**：中。

---

### 🅷 P 系列：要先由產品面定方向才能改程式（七組）

🔴 **這一整個系列不是「要不要修」，是「要修成什麼樣」**。建議**合成一張決策卡**請決策者一次裁完，而不是七張卡各問一次。

| 組 | 條 | 要決定什麼 | 狀態 |
|---|---|---|---|
| **P1** | 59 | viewer 能不能完成／退回稽核任務 | ✅ **已裁（2026-09-13）：不可以**，除非他就是被指派的人。**修法已定案，可以直接開卡**。⚠️ 修法範圍要含弱點掃描模組的八支改狀態端點（吃同一道守門，viewer 可發動帶帳密的掃描與刪紀錄） |
| **P2** | 74、75 | 客戶的管理員該不該有權改登入安全政策／日誌轉送目的地（現況：有權，而且改到的是**全公司共用的那一份**） | ✅ **已有第四個方向（2026-09-16）：只給客戶自己的第一層租戶（總部）改，子公司／部門不給；root 租戶維持不開放**。⚠️ 該案套到日誌轉送表**同樣要先改表結構**（那張表也只有全域一列、`tenant_id` 寫死 NULL） |
| **P3** | 80 | 設備與資訊系統清冊「只要登入就能看、不分權限」這個刻意取捨還算不算數 | 待裁。⚠️ **與意見回饋那五顆權限點（總表 §7 第 16 項）是同一種題**，建議一次裁 |
| **P4** | 41 | 讀不到自己的儲存設定時去借別家客戶的帳密，是不是刻意的「共用儲存空間」設計 | 待裁 |
| **P5** | 11、102 | AI 提示注入：使用者打字就能誘導 AI 選中 26 支查詢中的任何一支（11）／證據內文可以對 AI 下指令左右分類結果（102） | 待裁。102 要先定「AI 分類結果要不要當半可信」 |
| **P6** | 10 | AI 儀表板專案清單的「視同管理員」後門——**刻意設計、不是寫錯**，但在「使用者打字、AI 自己決定查什麼」這個新情境下從沒重新檢視過 | 待裁 |
| **P7** | 3 | 出貨時預設密碼的政策 | 決策者已裁「先記錄、之後再看」 |

**P1 與 P2 已經裁完了，可以直接開卡**——建議把這兩組從決策卡裡拿出來，**併進第二輪跟 A 系列一起做**。

---

### 🅸 I 系列：規劃上互相牽動（兩組）

#### I1 與 CM-1559 相依（2 條）

| 條 | 牽動關係 | 狀態 |
|---|---|---|
| 46 | 兩支背景排程靠「沒有登入身分時給最高權限」撐著，收緊 CM-1559 會讓它們**悄悄停止運作、不報錯** | ✅ 已修（改成具名系統身分） |
| 53 | 修第 53 條時要一併補 `advance_stage`／`rollback_stage` 兩處 | 仍在（已含在 A2） |

**第 46 項已修**，這組實質上只剩「修 A2 時記得第 53 項的連帶」這一句話。**不用獨立開卡**，寫進 A2 的卡片即可。

#### I2 空條件回全表（1 條 · 根因）

**第 70 項**：六張表的資料存取層沒有一支自己加專案範圍條件——全部走共用底層「查詢欄位有值才加條件、沒值就不加」的規則。**這個底層行為已經連續三次在不同套件放大成全庫外洩**（檔案清單、成員名冊、任務指派）。

**決策者 2026-09-15 已裁：要在底層擋，但分兩步。** 第一步先盤點全站哪些地方是**刻意**要查全表的（碼表、排程、管理員總覽），改成明確標記；第二步才動底層。**兩步之間可以隔很久。**

🔴 **第一步的起點已經備妥**——第十二任首腦做完的 17 支盤點清單（STATE「空條件回全表：全域盤點第一版」段），**下一任可以直接拿來用，不必重掃**。那份清單還附了判準：**看這張表的一筆資料有沒有「主人」**——有主人就該拒絕空條件，沒主人（碼表、公版、全站共用字典）回全表是正確的。

**建議**：這件事**獨立開一張卡**，不要跟 A3／A4 綁在一起——A 系列走的是「逐支補檢查」那條路，不等底層改。

---

### 🅶 X 系列：收尾（三組 21 條）

#### X1 一行小修合卡（11 條 · 建議開 1 張卡）

**這些問題彼此不相干，但都很小，一次順手做掉。**

| 條 | 修什麼 |
|---|---|
| 54 ＋ §3.2 13 | 階段推進／回退兩處 `ctx.setdefault` 改成直接覆寫（操作人一律以登入身分為準）＋資料格式定義加白名單 |
| 81 | 資訊系統修改的資料格式把「停用」欄位拿掉（**目前只有修改權限就能達成刪除效果**） |
| 93 | 問卷即時同步寫答案時「這筆是誰填的」改用登入身分，不採用前端送的名字 |
| §3.2 12 | 密碼產生器少算一個字元（`-4` 改 `-3`）——**目前產出的密碼可能通不過自家的密碼政策** |
| §3.2 21 | 「批次新增指派」死端點：後端只有 `return []`、前端仍在呼叫 |
| §3.2 24 | 問卷 Excel 匯入失敗時暫存檔永遠留在磁碟（刪檔那句移進 `finally`） |
| §3.2 26 | 正解匯入加筆數上限與型別檢查 |
| §3.2 27 | AI 分類設定的「預設廠商」「預設型號」存得進去但沒人讀 |
| §3.2 30 | 一段註解寫的跟資料庫實際規則相反 |
| §3.2 33 | 共用分頁查詢把跨欄位字串條件用「或」而不是「且」連接（**篩選條件被放寬不是收緊**） |
| C3 的 19／29／42／117 | 四條改預設值（見 C3） |

**建議**：**這張卡不要一個人做完**——15 個位置散在五、六支套件裡，按套件拆成兩三批平行做比較快。

#### X2 死碼與未接線清除（6 條 · 建議開 1 張卡）

| 條 | 刪什麼 |
|---|---|
| 20 | `db.py:97-99` 三行死碼——**留著會讓人誤以為那裡有一道組織層級的權限檢查** |
| 32 | 開發用的輔助工具混在出貨套件裡（會把檔案覆寫成空白、載入就讀 AI 金鑰環境變數） |
| §3.2 14 | `bpmn_generator.py` 三支吃檔案路徑、零呼叫者的方法——**是一個已經裝好、隨時可能被拿來任意讀寫檔案的陷阱** |
| §3.2 16、18b、23 | 三組「已接線但沒人用、且零權限檢查」的服務——接上去就等於憑空多出完全沒守門的入口 |

**這組的價值不在「現在有洞」，在「留著會害下一個人判斷錯」**。

**修法**：直接刪，或在組裝的地方加一句明確的提醒註解。§3.2 16／18b／23 那三組如果要留，**要標明「啟用前必須先修第 63 項」**。

#### X3 已修、不必開卡（4 條）

§3.2 第 7、8、9、10 項，兩次複查都確認修好了。**列在這裡只為了讓 145 條每條都有交代。**

---

### Z 單修（不成組，6 條）

**這些條目找不到能一起修的同伴，硬塞進哪一組都是勉強。** 標在這裡是誠實的分類結果，不是漏掉。

| 出處 | 條 | 是什麼 | 建議 |
|---|---|---|---|
| §3.1 | 28 | 員工被停權後登入憑證還能用約三天半，而且自己還能續到約八天 | **獨立開卡**。這條的修法橫跨停權動作、每個請求的身分確認、資料查詢層三處，跟誰都不同組 |
| §3.1 | 48 | 本機硬碟刪檔漏清轉檔產生的 PDF 備份（雲端那邊有清） | 併進 A1 順手做（同一支套件、同一個刪檔路徑） |
| §3.1 | 106 | 刪除整批之後，判定結果、容器報告、含原始檔名的清單全部永久留在主機工作目錄 | 獨立小卡 |
| §3.2 | 18 | 沒部門的使用者送意見回饋會失敗、畫面看不出原因 | **要先裁甲／乙／丙哪個修法**（總表 §7 第 17 項） |
| §3.2 | 28 | `SHARED` 範圍值三層各認一套，服務層那層是空的 | **總表標明「只回報待裁、不直接開卡」** |
| §3.2 | 29 | 套件自帶建表腳本的值域還停在舊版 | **同上，且屬出貨基線待重產類**——重不重產由決策者裁 |

---

## 4. 建議總表更正

**本棒只寫草案，沒有動總表一個字。** 下面是核對 145 條時發現的對不上的地方，**由首腦裁定後另派一棒改**。

| # | 在哪 | 現況 | 建議 |
|---|---|---|---|
| 1 | §3 標題 | 寫「還沒開卡的（141 項）」 | §3.1 實有 117 列 ＋ §3.2 實有 28 列 ＋ §3.3 實有 2 列 ＝ **147**；扣掉 §3.3 那兩條（是掃描本身的補洞、已有卡）＝ **145**。標題數字與小節標題都要重算 |
| 2 | §3.2 標題 | 寫「非資安但是真 bug（26 項）」 | **實際列了 28 列**（編號 7～33 連號，另有一列 `18b`） |
| 3 | §0「問題累積」表 | 寫「掃到了但還沒開工單的問題 143 項」 | 與 §3 標題的 141、實際的 145 三個數字互不相同 |
| 4 | §7 第 12 項 | STATE 已於 09-15 標註「總表 §6 第 12 項尚未改成已裁，下一任補」 | 該註記至今仍在，**這件事已經掛了五天** |
| 5 | §7「已裁決」末段 | 「等全部套件掃完再統一開卡」與「三個例外也不先做」（09-19 裁） | **掃描已於 09-20 收口**，這兩條的前提消失了。建議請決策者重新確認 C2 的第 83／84 項（撤銷權杖、清公開站密碼）要不要立刻處理——那兩件不占開發時間 |
| 6 | §3.1 第 34／40／47 項 | 原文仍寫「資料表沒有客戶歸屬欄位、資料庫隔離關閉」 | **已過期**（FR-107 為了別的目的補上了）。總表自己在複查段已經警告「開卡前原文必須改寫」，但原文本身還沒改 |

---

## 5. 這份草案沒有做的事

寫清楚免得下一棒誤會已經做過：

- **沒有開檔重驗任何一條**。狀態一律以總表自己的兩次複查為準；複查沒覆蓋到的照總表寫「仍在」。
- **沒有改總表、風險總表、STATE 任何一個字。**
- **沒有開任何 Notion 修正卡**——決策者要先看草案再裁。
- **沒有推翻決策者已裁的修法方向**（P1 viewer、P2 第一層租戶、CM-1559 順序、CM-1595 維持最嚴重等）。草案裡凡是已裁的，都照裁定寫。
- **沒有估工時**。每組的「涵蓋幾支套件幾個檔」可以當成規模的參考，但沒有換算成人天。
- **沒有判斷 jedi 套件的發版節奏**。草案只標出哪幾組動到套件（改了要發版才生效），**實際怎麼排發版是另一件事**。

---

## 6. 座標

| 要什麼 | 去哪 |
|---|---|
| 每一條屬於哪一組、有沒有漏 | [`classification-matrix.md`](classification-matrix.md) |
| 每一條的完整技術細節 | [`README.md`](README.md) §3 |
| 按風險等級排序的視角 | [`risk-overview.md`](risk-overview.md) |
| 現況與已裁決事項 | [`FR-075/handoff/security-scan-STATE.md`](../FR-075-2609-jedi-package-security-audit/handoff/security-scan-STATE.md) |
| 本卡 | CM-1983 |
