guidant-ai-be:1.21.0b4/FE 同版/agent 1.1.0b2,九容器 healthy)/api/1.0,自簽憑證 -k),五角色各拿一把 token 對同一資源分別打,記 HTTP 碼+error_code。07f4dcab…,in_progress,living SSP id2),五個租戶-3 帳號全部是該專案 participant,且全部掛 System Manager(滿權限)。因此 190 上做不出「同公司但非本專案成員」也做不出「無能力點」的帳號——除非建第二專案(見下)。admin(users.id=1)是 is_super_admin=t、租戶 1。它繞 RLS、可讀跨租戶,但不會自動加入專案——對專案 participant 守門一律吃 403 GRC_403053(實測 #52/#57 證實)。所以 admin 是「專案非成員攻擊者」的有效替身(對 project-participant 類守門),但不是「跨租戶 RLS 讀取攻擊者」(它本來就看得到全部)。route_capabilities 是 FE 選單用、非 BE runtime 守門來源,無法用它反推守門是否上線。第一輪誤把 blsemp1 當「攻擊者」對留言 CM1(2f602555…)送 PUT,結果 200 改成了「x」。但 blsemp1 其實是專案 1 成員、且是該留言作者——這是合法編輯、不是破口。已立即 UPDATE 還原內容為原值「評論一下」,收工前再查一次確認三筆留言內容原封不動。此後改用 admin(非成員)當攻擊者、blsadmin(manager)/blspan(auditor)/blsshino(reviewer)/blsemp1(viewer, 但仍是成員) 當角色梯度。
| n | CM | 一句 | 結果 | 證據 |
|---|---|---|---|---|
| 5 | 2034 | 填答歷史明細空請求讀全公司 | ✅ | 【三輪】POST /project-survey/history-details(task_survey_id=1):blsview(非成員)→403 GRC_403053、blsfrank(跨租戶)→404、blspan/blsemp1(成員)→200。歸屬守門生效 |
| 6 | 2034/2038 | 拿問卷編號讀別部門答案 | ✅ | 【三輪】GET /project-survey/answers/<ts_uid>:blsview→403 GRC_403053、blsfrank→404 TASK_SURVEY_404005、成員→200。歸屬守門生效 |
| 7 | 2035 | 拿任務編號讀別家證據清單 | ✅ | GET /job-evidence/<ev>:admin(非成員)→403 GRC_403053;成員讀正常。歸屬檢查生效 |
| 8 | 2035 | 讀/塞別人專案留言 | ✅ | GET /grc/job-executions/<je>/comments admin→200 空(該 je 無留言,非破口);PUT /grc/job/comment/<cm> admin(非成員)→403 GRC_403003 無權限操作此留言。歸屬+作者守門生效 |
| 40 | 2031 | 檢查流程圖端點無權限無大小限 | ⚠️ | POST /flow-engine/flow-templates/validate 我構造的 xml 一律被 400 COMMON_400001 擋在 schema 前,觸不到能力閘與上限邏輯。無法乾淨驗證,打折(未見放行) |
| 41 | 2023/2071 | 自建專案填別人任務指派 | ✅ | POST /task-assignee admin(非成員)→403 GRC_403002 不具管理者角色;blsshino(reviewer)→同 403。寫入守門生效 |
| 46 | 2040/2178 | 子公司改分享範本控制項清單 | ✅ | 【二輪】blsfrank(租戶4) PUT /module-frame/<t3-mf>/control-defaults/<ctrl> → 被擋、MF 名未變;RLS 讓 t3 範本對 t4 不可見 |
| 48 | 2034 | 列任務問卷空請求拿全公司 | ✅ | 【三輪】單筆 GET /task-survey/<uid>:blsview→403、blsfrank→404、成員→200;列表 POST /task-surveys blsfrank 回空(RLS 過濾)。一輪必填檢查+三輪歸屬雙證 |
| 49 | 2034 | 列填答歷史空請求跨專案 | ✅ | 【三輪】選單 GET /project-survey/histories/menu/<uid>+列表 POST /project-survey/histories:blsview→403、blsfrank→404、成員→200 |
| 50 | 2034 | 問卷討論列表空查詢撈全公司 | ✅ | 【三輪】POST /survey-discussions(survey_uid+task_survey_uid):blsview→403 GRC_403053、blsfrank→404、成員→200。歸屬守門生效 |
| 51 | 2034 | 進任意問卷房間旁聽 | ⚠️ | on_join 走 SocketIO,非 REST;190 無填答資料、未經 socket client。打折(原因②③,非原因①,維持) |
| 52 | 2035 | 拿輪次編號讀別家階段歷程 | ✅ | GET /project/<p>/audit-round/<r>/stage/transitions admin(非成員)→403 GRC_403053;成員→200。project_uid 真比對生效 |
| 53 | 2035 | 查目前階段角色不核對整包回傳 | ✅ | GET /.../stage/info admin(非成員)→403 GRC_403001 不具稽核員角色(擋在前,未整包回傳);成員→200 |
| 54 | 2036 | 專案成員查詢空白拿全公司名冊 | ✅ | GET /project-participants/menu+POST /project-participants 空 → 400 PARTICIPANT_400002 project_id 為必填。必填生效 |
| 55 | 2036 | 換編號讀別人專案群組/控制項配置 | ✅ | 【二輪】同族 #54/#58 blsfrank(跨租戶,numeric project_id=1) 皆 403 GRC_403053;pcp 專屬端點因 project_control_participants 表空、成員 blspan 也回 404,無資料可獨立驗,以同族佐證 |
| 56 | 2037 | 換編號讀別人專案摘要報告全文 | ✅ | 【二輪】blsfrank POST /project-summary-reports → 200 但 total:0(RLS 藏住 t3 的,跨租戶讀不到);列表「只列我參與」需有資料才驗完整,跨租戶隔離已證 |
| 57 | 2037 | 換編號讀輪次判定風險改善計畫(十入口,團隊名單跨客戶) | ✅ | 【二輪】blsfrank 跨租戶:round single/list/AP/findings 全 404 GRC_404038/404001(稽核輪次/專案不存在)。跨客戶讀已擋;AR 內容細部(findings 資料層)仍需走到稽核中的輪次才驗得到 |
| 58 | 2036 | 任務指派清單空查詢拿全公司萬筆 | ✅ | POST /task-assignees 空 → 412 PARTICIPANT_412001 project_id 或 task_uid 需擇一提供。必填生效 |
| 59 | 2036 | 底層空查詢=回整表(已裁逐支補) | ✅ | #48/#49/#50/#54/#58 均已在各端點補必填(見上各列),逐支止血策略生效;底層未動屬預期 |
| 64 | 2041 | 刪控制項佐證只查計畫不查文件歸屬 | ✅ | DELETE /ssp/<lssp>/control-implementation/<ctrl>/reference-document/<bogus> blsadmin(manager)→404 GRC_404049 參考程序書不存在或不屬於此計畫。歸屬比對生效 |
| 65 | 2040/2179 | 建立合規資源庫的入口完全沒有權限檢查 | ✅ | 【二輪】blsfrank(有 module-frame.create) 建庫→200(自租戶、有能力,屬正常);#195 已證草稿版本被 412 擋。能力閘存在(無能力帳號不存在,無法反證放行,但正向行為正確)。⚠️ 本項建了一筆 t4 測試資源庫 zzfrank,已 API 刪除(soft-delete,is_delete=1,見事故段) |
| 68 | 2044 | 群組層成員增改刪整支不檢查 | ✅ | 190 實測 POST/OPTIONS /control-group-participant → 404(路由不可達,死碼已拆) |
| 69 | 2044 | 流程參與者整組壞守門 | ✅ | /process-participant* 不在 190 路由表(已拆) |
| 85 | 2060 | 填答者署名別人 | ⚠️ | 走 SocketIO on_update,190 無填答資料、未經 socket client 驗。結構上已改用登入身分(程式層),行為層打折 |
| 87 | 2059 | 空白流程範本讓清單頁全壞 | ⚠️ | POST /flow-engine/flow-templates 空 xml → 400 COMMON_400001(schema 擋在前);讀取端容錯(清單頁不 500)需有壞資料才驗,打折 |
| 88 | 2059 | 範本增改不檢查、草稿也能起輪次 | ⚠️ | create/update 被 schema 400 擋前置,起輪次需走完整流程;未能乾淨驗,打折 |
| 102 | 2055 | 匯出 Word 使用者文字未跳脫 | ⚠️ | 需匯出並開檔驗 autoescape,API 層驗不到,打折(屬匯出檔內容檢查) |
| 110 | 2023 | 更新成員撈不到就跳過管理者檢查 | ⚠️ | 需構造「撈不到既有紀錄」情境,靠後道檢查頂住;#41 寫入守門已證有效,此細節打折 |
| 115 | 2035 | 讀全部流程範本內容(選單擋、功能敞開) | ✅ | 【二輪】blsfrank GET /flow-engine/flow-templates 只回 SYSTEM 範本(tenant 1),看不到 t3 的 TENANT 範本 050f…test;跨租戶不洩漏 |
| 120 | 2044/2178 | 四支任務指派功能無入口無守門(裁定刪三留一) | ✅ | POST /task-assignees/batch 活著(壞 body→400,FE 快速配置不能壞);被刪三支不在路由表 |
| 126 | 2060 | 塞內部開關叫出隱藏資料夾 | ✅ | POST /survey-folders 帶 is_delete:true → 200 但只回 is_delete:"0" 的資料夾(隱藏開關被程式寫死忽略)。生效 |
| 127 | 2060/2181 | 型別不對吐 SQL 原始錯誤 | ✅ | 帶 is_delete:"notabool" → 200 正常清單(型別被容錯忽略,未吐 SQL/表名)。無錯誤洩漏 |
| 128 | 2059/2188 | 推進退回操作者名稱可自填 | ⚠️ | 走階段推進流程,需輪次在對應階段;結構上暱稱已改伺服器強制覆寫,行為層打折 |
| 146 | 2040/2178/2187 | Excel 蓋既有範本不問你是誰(唯讀稽核員也能) | ✅ | 【二輪】blsfrank Excel source_type=module_frame&source_uid=<t3-mf> → 404 GRC_404021;跨租戶覆蓋被擋 |
| 147 | 2178/2187 | Word 版蓋既有範本 | ⚠️ | 【二輪】blsfrank Word 覆蓋在 GRC_400007 缺 framework 參數 前置擋下、未觸達 source 檢查;與 #146 同缺口、Excel 側已證擋。Word 側打折(參數形未完整構造) |
| 148 | 2188/2189 | 拿 SSP 編號整份下載 Excel(跨客戶) | ✅ | GET /ssp/<living-ssp>/excel-template admin(非成員)→403 GRC_403051 僅專案管理者可編輯 SSP;成員(blspan)→拿到檔。跨專案下載已擋 |
| 153 | 2173/2178 | 管理者掛別人專案文件到控制項 | ✅ | POST /ssp/<lssp>/control-implementation/<ctrl>/document-mappings 帶別 SSP 的池文件 uid → 404 GRC_404049 不屬於此計畫;帶 bogus uid → 同 404(非靜默 200)。歸屬生效 |
| 155 | 2183 | 框架 PDF 解析失敗吐路徑/套件名/SQL | ⚠️ | POST /oscal-framework-parse-jobs/parse 帶必填 meta+junk pdf → 400 COMMON_400001(擋在 schema 層,未到解析器)。未見任何路徑/stack 洩漏,但解析錯誤路徑本身未觸及,打折 |
| 156 | 2180 | 刪框架/版本不查客戶資源庫在用 | ✅ | admin(root) 刪被資源庫引用的版本 1cd9fbd6 → 409 GRC_409038 已被合規資源庫使用,不可刪除;刪其所屬框架 → 同 409。引用檢查生效 |
| 157 | 2186 | 員工直接打網址讀全公司範本清單/內容 | ✅ | 【二輪】blsfrank GET /module-frame/<t3-mf> → 404 MODULE_FRAME_404001;/module-frames/menu 回空。跨租戶讀不到 |
| 158 | 2186 | 稽核流程圖任何人讀(增改刪要權限) | ✅ | 【二輪】blsfrank GET /module-frame/<t3-mf>/control-defaults → 404;跨租戶讀不到(能力閘+歸屬) |
| 159 | 2178 | 改流程圖只在改分享時才查歸屬 | ✅ | 【二輪】blsfrank 對 t3-mf 各寫入端點全 404(RLS 不可見,改分享與否都碰不到) |
| 160 | 2178 | 刪改範本子項查網址不查送入的範本 | ✅ | PUT /module-frame/item/<bogus-child> 帶 moduleFrameUid → 404 GRC_404027 流程範本不存在(先查網址子項存在性)。生效 |
| 162 | 2186/2193/2212 | 稽核目標預設任何人讀 | ✅ | 【二輪】blsfrank GET /module-frame/<t3-mf>/objective-defaults → 404;跨租戶讀不到 |
| 163 | 2171/2186 | 範本人員/設備/元件/繼承任何人讀(跨公司) | ✅ | 【二輪】blsfrank 對 t3-mf 的 parties/inventory/components/leveraged/system-characteristic/ssp-resources/reference-documents 全 404;跨公司讀不到 |
| 164 | 2171/2187 | 管理員改分享/公版範本六類附屬資料 | ✅ | 【二輪】blsfrank 對 t3-mf 六類 add/update 全 404;跨租戶寫入被擋、MF 未變 |
| 165 | 2187/2194 | Excel 批次存範本控制項只查存在 | ✅ | 【二輪】blsfrank POST /module-frame/<t3-mf>/control-defaults/import/validate → 404 MODULE_FRAME_404001;跨租戶被擋 |
| 166 | 2176/2189 | 計畫內容填公式下載時執行 | ⚠️ | 需下載 Excel 開檔驗 set_text_cell,API 層驗不到,打折 |
| 168 | 2174/2178 | 只有建立權限走匯入改既有範本 | ⚠️ | 需「只有 create 無 update」帳號;blsview(首腦說要建的低權限帳號)在 190 不存在,190 帳號皆滿權限。無法驗,打折(原因①殘留,缺帳號) |
| 178 | 2186/2195 | 設備/資訊系統對照任何人讀(附資產內部編號) | ✅ | 【二輪】blsfrank GET /module-frame/<t3-mf>/ssp-resources → 404;跨租戶讀不到 |
| 180 | 2174/2190 | 幾 KB YAML 讓伺服器算到當掉 | ⚠️ | 需上傳惡意 YAML 走 /module-frame/import/yaml 完整流程;未在本卡範圍構造惡意檔實壓(屬效能/DoS,非權限),打折 |
| 181 | 2181/2217 | Excel 匯入檢核送長字串佔住兩分鐘 | ⚠️ | 同上,DoS 類需惡意檔+計時,打折 |
| 190 | 2184/2218 | 判定接風險不查同一份結果 | ⚠️ | 需走到有 AR result 的輪次;190 輪次 planning,無稽核結果,打折 |
| 193 | 2184 | PDF 超長行卡目錄比對兩分鐘 | ⚠️ | DoS 類需惡意 PDF+計時,打折 |
| 194 | 2183/2204 | Word 打不開錯誤回暫存路徑 | ⚠️ | /ssp-docx-imports/parse junk docx → 被 400 GRC_400007(缺 framework 參數)擋在 schema 前,未到解析器。未見路徑洩漏,解析錯誤路徑未觸及,打折 |
| 195 | 2179 | 草稿版本編號拿去建資源庫 | ✅ | POST /oscal/resource-libraries 帶草稿 fv → 412 GRC_412057 框架版本尚未發佈,無法用來建立合規資源庫。已發佈版本正常。生效 |
| 197 | 2195/2213 | 兩張解析工作單隔離照抄壞寫法 | ⚠️ | RLS policy 需以 cm_app 模擬子租戶身分查 ap/ar parse job 表;190 無跨租戶 parse job 資料,且屬 DB-policy 層,打折(程式層另有擋) |
| 198 | 2174/2203 | 匯入前改資料塞外部佐證 | ⚠️ | 需走稽核結果匯入預覽→改 body→確認,需 AR 流程,打折 |
| 224 | 2208 | 流程圖存檔刪方塊硬刪別人任務 | ⚠️ | 需流程圖編輯器 sync 流程+可反查專案的實例;API 層難精準構造,打折(結構上已在 sync 層加管理人檢查) |
未見任何 500 洩漏或路徑/stack 洩漏:所有跨租戶請求都回乾淨 403 GRC_403053(非成員)或 404 GRC_404021/404038/404001/MODULE_FRAME_404001(RLS 讓資源對外租戶不可見),無 500、無 SQL/路徑外洩。既有 /module-frame(list)、/survey(list) 兩支 500 仍是無關既有 bug。
首腦在卡末段建了 blsfrank(users.id=7、租戶 4 Billows-子公司、System Manager)解掉「無跨租戶帳號」的打折。本輪用 blsfrank 打租戶 3 全部資源,結論:
project_id(非 project_uid)才觸達守門:blsfrank→403 GRC_403053。(serializer 吃 project_id:int,傳 project_uid 會先被 schema 400 擋掉,非安全結果。)blsview 未建:卡上首腦補充只寫了 blsfrank,190 users 表無 blsview(id 只到 7)。且租戶 3 每個角色(含「唯讀檢視者」)本來就都有 module-frame.read,即便 blsview 存在也擋不出「無能力點」效果。能力閘(無 read 能力被擋)這一類仍無帳號可驗——影響 #168,維持打折。
a581499a…、連帶 clone catalog id 7)。這是「有能力者在自己租戶建立」的正常行為、非破口。已用 API DELETE /module-frame/<uid> 刪除,回 200;產品的刪除是 soft-delete(is_delete=1、row 保留、catalog 7 仍在),這是 API 能做到的最乾淨可逆狀態;不手動硬刪 catalog/profile/ssp(那比留一筆 t4 soft-deleted 測試列風險更高)。t3 正式範本 2a2f19f0…(CMMC 2.0 Level1) 全程未受影響。首腦在 190 建了 blsview(id=8、租戶 3、只有「唯讀檢視者」、非任何專案成員)與一份填寫中的任務問卷(專案 2、task_survey uid 5a94e666…),解掉「問卷表全空、無低權/非成員帳號」的打折。
四身分打 #5/#6/#48/#49/#50,全部呈現理想形狀:
| 身分 | 期待 | 實測 |
|---|---|---|
| blsview(同租戶、非成員、有 survey.read) | 被歸屬擋 | 全 403 GRC_403053 非此專案參與者 |
| blsfrank(子租戶) | 跨租戶擋 | 全 404 TASK_SURVEY_404005/404001(RLS 不可見) |
| blspan(成員 auditor,非指派人) | 可讀 | 全 200(CM-2034 已放寬為「任何專案成員可讀」) |
| blsemp1(成員 viewer,指派人) | 正常讀 | 全 200 |
403、跨租戶讀 404、成員讀 200,三態分明。history_uid 或 task_survey_id(非 task_survey_uid)才觸達守門;填答歷史/明細目前無資料(0 筆),但守門在回資料前就先擋,非「查無所以空」。統計更新:✅ 39 條、打折 20 條(59 條總計;三輪把 #5/#6/#48/#49/#50 五條轉正,二輪計數含一條重複已校正)。剩餘 20 條打折只剩原因②(190 資料狀態:SocketIO 房間類 #51/#85、AR 結果類 #190/#198 等)③(解析錯誤路徑 #155/#194/#40/#87/#88)④(DoS/匯出檔內容 #102/#166/#180/#181/#193),原因①(無跨租戶/無成員/無低權帳號)已完全消除。