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

FR-087 租戶隔離破洞盤點

已盤完並經首腦驗收(2026-09-11)。13 張表+4 支 view+1 條應用層洞+1 項待裁項,逐項五問全答,含「開了會不會弄斷」的查證。卡 CM-1663

狀態:✅ 已完成 文件 1 份

🔴 一頁看完

已盤完。 完整報告:scan-T1-isolation-gap-audit.md

這批的來源是 FR-080 併入當天的交接:決策者實測發現切換到被指派的子租戶之後,還是看得到別家客戶的待辦任務與專案。決策者裁定隔離修正歸資安線這邊做,與 FR-086「只驗身分不驗歸屬」那批一起看。

§1

這在做什麼(白話)

產品是多家客戶共用一套系統的,靠資料庫的一道機制把各家資料隔開(RLS,就是「每個客戶只能看自己資料」的資料庫隔離機制)。

這一棒要把**「哪些資料該被誰看到」逐張表盤清楚**,列出現況與應有狀態的差距,交給決策者決定怎麼修。不修、不改、不套任何 SQL。

§2

🔴 不是理論風險,已實測

拿一把指向不存在租戶的鑰匙去查(首腦在 DEV 用受隔離的應用帳號重跑過,數字與交接檔一致):

查什麼 應該看到 實際看到
待辦任務列表 0 筆 39 筆
專案 0 筆 213 筆
任務執行紀錄 0 筆 11,065 筆
工作流執行紀錄 0 筆 11,016 筆

目前客戶端還沒炸:跨租戶指派在 STG/POC 是 0 筆。但那個功能已經可用了,所以是「還沒有人踩到」而不是「踩不到」。

§3

為什麼今天才發現

這是一個修好一個洞才露出來的更大洞。 以前沒人切過租戶——切租戶要先被指派成別租戶的角色,而那個功能在 CM-1661 修好前根本不能用。修好之後才看見後面的隔離沒做。

§4

決策者已定的產品模型(判準,不重新設計)

垂直向下可管理(父租戶看得到子孫),不同分支互相隔離;平台級資源(法規框架、控制項目錄、內建範本)全租戶可讀、只有原廠可寫。

這個模型 2026-06-29 就定了,原文在 docs/changelog/2026-06-29-feat-tenant-scope-data-model-b2.md

§5

盤什麼(首腦已在 DEV 實查,13 張表與 4 支 view 與交接檔一字不差)

類別 數量 說明
政策寫好但沒開 3 張 專案(4 條)、工作流範本(4 條)、雲端整合(4 條)。開開關即可
政策不完整 1 張 工作流執行(只有 3 條、缺 SELECT
連政策都沒有 9 張 任務執行、資訊系統、POAM、證據分類兩張、框架解析、日誌轉發、使用者角色、使用者租戶
view 繞過隔離 4 支 待辦列表、能力、路由兩支。PG16 的 view 預設用擁有者身分查底層,而擁有者是超級權限帳號

⚠️ 交接檔摘要寫「三支 view」,實際是四支(正文清單有列全)。以四支為準。

另有一條應用層的同型洞(決策者裁定歸本棒):任務詳細 API 收了專案編號卻從頭到尾沒用它api/flow_control/routes/job_route.py:75-92,首腦已開檔核對屬實)。與 FR-086 B1 完全同型,修法可併。

§6

🔴 本棒最重要的一項:開了隔離會不會弄斷現在的功能(已查證,見報告 §6)

  • 背景任務會受影響:每天凌晨 3:10 有一支自動清理程式(找「已刪除任務仍留著的綁定資料」)掃描 job_executions 全表,它能看到全部客戶資料,靠的正是「無身分時暫時給最高權限」那條規則(CM-1559)。開隔離本身不會斷它(它沒有「自己的租戶」這個概念),但若之後 CM-1559 那條規則被收緊,這支清理程式會安靜地停止運作、不報錯——兩件事必須排進同一輪規劃。另一支每天凌晨 1:00 清舊工作紀錄的排程同款成因、影響較小。
  • 平台管理功能不受影響(已更正原本待查項目):追查後確認原廠管理者判斷「我是不是平台管理員」,走的正是 RLS 判斷「我是不是最上層租戶」同一段邏輯(_session_paths_have_root)——不是靠隔離沒開才看得到全部客戶,是合法的『上層看下層』。開隔離不影響平台管理後台。
  • AI 儀表板 27 支查詢是獨立的洞,不是同一個機制:FR-083 查出的問題是「動態組查詢,完全不檢查權限」,走的程式路徑跟本棒盤點的資料庫層隔離不是同一批,修一邊不會弄斷或修好另一邊,兩者分開處理。
§7

為什麼不用掃描工具

這一棒的答案在資料庫狀態與 SQL,不在程式碼的漏洞模式,工具幫不上忙。人工查快又準,而且這樣才能與 FR-086 B1b 平行跑不搶額度

§8

進度

範圍 狀態 報告
T1 隔離缺口盤點 CM-1663 13 表+4 view+1 API+1 待裁項 ✅ 已盤完(2026-09-11) 報告
§9

盤點結論摘要

  • 甲組(純開關即可)compliance.projects(開前先查當初關閉原因)、public.tenant_drive_integrations
  • 乙組(補規則再開開關)job_executionsinformation_systemspoamsevidence_classification_runsevidence_classification_ground_truthframework_parse_jobsuser_rolesuser_tenants
  • 丙+丁組(要一起修)workflow_executions(補 SELECT 規則)+ 4 支 view(加 security_invoker)——vw_user_job_queue 跨 12 張表,含丙組那張,必須同一輪驗證
  • 戊組(先處理資料才能開)workflow_templates——191 筆凍結副本無客戶歸屬,要先回填
  • 庚組(等決策者裁)surveyssurvey_folders 要不要加平台旗標(報告 §7 給三個選項)
  • 辛組(建議重新分類,不當隔離缺口)log_forwarding_settings——本質是平台層設定,已有能力點守門
  • 壬組(應用層洞,與 FR-086 併):任務詳細 API 不驗 project_uid(GET/PUT/DELETE 三支)
§10

修正卡

(依決策者裁定,修正卡先不開,發現登記進跨 arc 總表 §3。)

§11

座標

  • 來源交接檔FR-080/handoff/fr080-to-fr075-HANDOFF.md §二(證據與修法方向已寫全)
  • 三層模型原文:docs/changelog/2026-06-29-feat-tenant-scope-data-model-b2.md
  • 標準規則寫法:docs/system-design/database/RLS_DESIGN.md
  • 同型前案:FR-086(四層全空)、CM-1559(無身分時隔離關掉)、FR-083(AI 儀表板 27 支查詢不經權限檢查)
  • 跨 arc 總表:security-scan-consolidated/

FR-080 的其餘收口七項(M3 裁決、五支發版、pin 還原、e2e 假綠、SPEC、母卡、release note)歸 FR-080 首腦,不在本 arc。

§12

文件

以下全部由 build 掃資料夾產生,新增檔案重 build 即自動出現。標題連結指向渲染後的 HTML,md 連向源檔。

其他文件

文件 類型 標題 最後更新
scan-T1-isolation-gap-auditmd 文件 FR-087.T1 盤點報告:租戶隔離破洞逐表對照 2026-09-11
§13

Notion 卡

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

關係 卡號 標題 狀態
母案 CM-1663 FR-087 租戶隔離破洞盤點(一棒,只盤不修,不用掃描工具)