FR-096 · 需求索引 · 本頁由 build 掃資料夾生成

FR-096 系統設定與選單字典(jedi-system-core)資安檢查

🟡 三棒已開卡,全部待派(2026-09-15)。母卡 CM-1803;子卡 CM-1804~1806 三張一次建完連號。套件 57 檔+宿主 25 檔,按「密碼在哪、權限在哪」切三棒共 82 檔:P1 設定表全鏈(24,jedi)→ H1 主專案接線(25,BE)→ P2 選單字典全鏈(33,jedi),一次只派一棒。這支跟前面幾支的風險形狀不同——前面掃的是「誰能看誰的資料」,這支是系統自己的鑰匙(寄信/LDAP/物件儲存的帳密)與全站生效的總開關。首腦開卡時已開檔核出四處繞過守門版服務、一行把密碼寫進日誌、遮罩名單漏掉物件儲存那一組。

狀態:🟡 進行中 文件 0 份

🔴 一頁看完

這支還沒開始掃,三棒卡都開好了,等發令。

這一支跟前面幾支不一樣。前面掃的是「誰能看到誰的資料」——客戶 A 撈得到客戶 B 的名冊、任務、檔案。這一支存的不是客戶資料,是系統自己的鑰匙:寄信伺服器、LDAP 目錄服務、物件儲存的連線設定,裡面有帳號和密碼。一把寄信密碼外流,攻擊者能用公司名義寄釣魚信;一把物件儲存密碼外流,所有客戶上傳的檔案都在他手上。而且改設定是全站生效的總開關——改掉 LDAP 伺服器位址,等於把全公司的登入驗證導去攻擊者的機器。

首腦開卡時已經開檔核出三件事(未經三人檢查員面板驗證,寫進卡當錨點):

  1. 四個地方繞過了「守門版」服務。 主專案本來把兩條產品規則(出廠快照要藏起來、共用設定要落在總部那一列)包成一支守門版服務,設計意圖寫得很明白:「單一收口點,所有使用者拿到同一個過濾後的視圖」。但另外四支組裝檔用的是未包裝的原版auth_containers.py:180notification_containers.py:20user_change_password_containers.py:46,加上 login_containers.py 直接接底層)。這四條路徑是登入、寄信、改密碼——全都會碰到寄信伺服器的密碼。
  2. 讀設定會把整列內容(含密碼原文)寫進日誌檔。 system_config_service.py:20 一行把整包塞進 log,而設定列的內容是 JSON,寄信那列裡面就是「密碼欄位:真密碼」。這是總表已登記的「密碼寫進日誌」那幾條(FR-085 C2 HIGH)的源頭表。
  3. 遮罩名單漏掉物件儲存那一組。 套件 plugin/contract.py:61 的名單有四組、沒有儲存設定:65 的機密欄位名只有兩個、沒有物件儲存帳密用的那兩個欄位名。FR-086 B2-A 已從上傳那一側報過這件事(HIGH),這次要從名單這一側確認是不是同一個根因。

資料庫實查(首腦 2026-09-15 對 DEV 唯讀):設定表有隔離(4 條規則),23 筆分佈在 6 個客戶,其中 6 筆的密碼欄位是有值的——不是空表,真的有東西可偷。

總進度表

範圍 檔數 狀態 首腦驗收
P1 CM-1804 設定表全鏈+插件契約與四道守門殼(jedi 套件) 24 檔 1,674 行 待派(第 1 棒)
H1 CM-1805 主專案接線:守門版服務+繞隔離讀寫器+四支 DI 組裝(BE repo) 25 檔 2,672 行 待派(第 2 棒)
P2 CM-1806 選單字典全鏈(jedi 套件,含 13 支空檔) 33 檔 842 行 待派(第 3 棒,收尾)

一次只派一棒,每棒獨立驗收完才派下一棒。合理停損點在第 2 棒之後(P1+H1 共 49 檔已涵蓋全部的密碼與權限風險面),但沒跑完三棒不能宣稱「這支套件掃過了」

需求討論紀錄

§1

為什麼這樣切

三棒的分界是「密碼在哪、權限在哪、其餘」

  • P1(設定表,jedi 套件)——密碼全在這一半。從端點一路到資料庫的完整路徑、四道守門的接法、遮罩機制、隨包的三支 SQL(建表/隔離規則/預設值)。風險最高,先跑。
  • H1(主專案接線,BE repo)——「誰改得動」與「有沒有繞過守門版」的答案都在這裡。套件的說明自己就寫著「四道守門一律由宿主注入」「權限分流表是產品的角色矩陣、留在宿主」,那張表就在這一棒範圍內。跨 repo 必須分棒(工具一次只吃一個掃描根目錄)。
  • P2(選單字典,jedi 套件)——內容已查證是無個資的碼表,風險最低,但要跑完覆蓋率才完整。收尾。

為什麼不按分層水平切:權限漏洞活在層與層的接縫上,只給端點或只給服務兩邊都看不出來。三棒都是從端點一路到資料庫的完整垂直切面。

為什麼設定與選單不合成一棒:合起來 57 檔超過一棒的上限(面板成本=候選數×3 個檢查員,每個從零讀檔),而且兩張表的租戶語意刻意相反(設定要隔離、選單要共享),混在一棒會讓研究員把兩套標準搞混。

§2

已經查證過的,掃到不要重報

選單表沒有客戶隔離,是正確的,不是漏洞。 首腦 2026-09-15 對 DEV 實查:這張表沒開隔離、0 條規則、共 74 筆,內容全是下拉選單的碼表(使用者狀態、啟用狀態、問卷題型這類),沒有客戶資料、沒有個資。選單字典是全站 UI 的資料來源,隔離起來會壞掉所有頁面。套件的說明也寫明兩張表的語意刻意相反:「設定是每個客戶自己的參數,選單是全站共用的字典」。

但有一件相關的事要記一句:查選單的請求格式六個欄位全部非必填,送一個空的查詢條件就回全表。以這張表的內容而言影響有限,但它屬於首腦正在盤的「共用底層送空條件就回全表」那條線(跨 arc 總表 §6 A 組第 15 項,已經第三次撞到)。報告寫一句歸那條線即可,不要當獨立發現升級

§3

共同設定

項目
主 session 模型 Opus 5 (1M context),不要用 Sonnet(研究員繼承主 session 的 context 上限,Sonnet 跑不完會被工具的「180 秒沒動作就判當掉」砍掉重派)
effort low(單一研究員掃全範圍+三人檢查員面板,不跑盤點、不做威脅建模)
focus attack-surface(跳過測試、打包產物、文件)
派工節奏 一次只派一棒,驗收完才派下一棒
§4

相關座標

§5

Notion 卡

卡片內容(決策紀錄、驗收條件)以 Notion 為準,本頁只記座標。

關係 卡號 標題 狀態
母案 CM-1803 FR-096 掃 jedi-system-core(系統設定與選單字典:寄信/LDAP/物件儲存的伺服器設定)資安掃描(三棒 82 檔,只掃不修)
子卡 CM-1804 P1 設定表全鏈+插件契約與四道守門殼(24 檔,jedi 套件) Not started
子卡 CM-1805 H1 主專案接線:守門版服務+繞隔離讀寫器+四支 DI 組裝(25 檔,BE repo) Not started
子卡 CM-1806 P2 選單字典全鏈(33 檔,jedi 套件) Not started