FR-088 · 需求索引 · 本頁由 build 掃資料夾生成
✅ 六棒全部掃完並驗收(2026-09-14 驗收 P2);發現已全數處理——M06 23 件已修(1.21.0 出貨)、1 件裁定刪除。P2:套件本體 49 檔沒有新發現——唯一 3:0 通過的一條是流程留言零守門,H2 已登記第 51 條,本棒從套件側證實「套件層也一行檢查都沒有」;6 票全投、verified、交付四件齊全。最有價值的產出是對照表:套件 WorkflowExecutionService 主專案根本沒 import(宿主整支重寫了自己的),JobExecutionService 接在 DI 容器裡但零取用(未來陷阱,登記 §3.2 第 16)。六棒合計範圍內 12 條(各棒 runner 報數加總 3+4+2+2+1+0;登記為總表 §3.1 第 49~59 共 11 列——H1 兩位研究員各報一次的同一個洞併成第 52 條——+§3.2 第 13~16 共 4 條非資安)。母卡與六子卡已 Done,收口 SUMMARY 見 handoff/2026-09-14-FR-088-SUMMARY.md;修正卡本線不開,程式層那批併 FR-086、資料庫層歸 FR-094。
第 1 棒 H2 掃完了。結論:任何一個能登入的帳號,只要知道一個任務編號,就能讀走別家客戶的稽核證明清單(檔名、描述、雲端硬碟連結、上傳者、檔案指紋)——系統只檢查「你有沒有登入」,沒檢查「這個任務是不是你們專案的」。 同一個檔案裡新增/更新/刪除三處都有檢查,只有「讀」漏掉,是漏寫不是設計。流程留言的讀與寫也一樣漏了,任何登入者可對別人專案的流程塞留言、還會即時推播給該專案成員(可拿來假冒同事釣魚)。而這幾張表在資料庫層的隔離全是關的、job_evidences 與 element_variables 連租戶欄位都沒有——與 FR-086 檔案存取「四層全空」同一個病。三條共用一道修法:補一行既有的 assert_project_participant(...)。
開卡時的八個疑點:五成立、兩證偽、一無問題。 證偽的一項值得記:守門檔註解寫「tenant admin 放行(RLS 仍限租戶)」,追到源頭那個旗標其實是平台超級管理員,所以「租戶 A 管理員動租戶 B」不成立;但註解錯了、它宣稱的兜底也不存在。
📄 H2 報告
第 2 棒 H1 也掃完了。結論:任何登入者只要知道一個輪次編號,就能讀走別家客戶的稽核階段歷程,包括每次退回是誰做的、退回理由全文(網址上帶的專案編號程式從頭到尾沒用過)。「查目前階段」那支也一樣:用你填的專案編號查角色、用你填的輪次編號撈資料,兩者不核對,角色不符也不擋、照樣回整包資料(含流程執行編號,那是另一批 API 的鑰匙)。但開卡時最大的疑點「跨專案推進/退回別人的稽核」經查寫不成立:下游的稽核輪次套件會拿輪次自己的專案再查一次角色,七條寫入路徑首腦逐一開檔核對都有。只是擋住它的是別人不是本層,哪天新增一支不走那個套件的 handler 洞就開了。force 雙版本三個檢查員 0:3 否決、首腦同意:錯位真的存在,但只能跳過設計上就是「軟提醒」的規劃就緒檢查,真正的守門全看外層變數。另發現推進/退回的操作者顯示名稱可由呼叫端自填(權威帳號欄不受影響,LOW)。
H1 的證偽比證實更有價值:兩個最大疑點一個「讀成立寫不成立」、一個「不成立」,三條被否決的候選首腦獨立追完整攻擊路徑,結論與檢查員一致。runner 另抓到工具一處錯誤(它宣稱 compliance.projects 有 RLS,實查沒有,門檻反而更低)。
📄 H1 報告
第 3 棒 P1 也掃完了。結論:一張惡意流程圖能把伺服器卡死。 程式沿流程圖的分岔點往下走時不記得走過哪裡,「分岔點繞回自己」的圖每次讀都 500;更糟的是「一路串接 40 個分岔點」的圖,程式把同一個分岔點算兩次、每多一個工作量翻倍,永遠算不完、連錯誤都不報,一條工作執行緒就卡死,多打幾次整個系統對所有客戶不回應。存進去是一次性動作(要有存流程圖的權限),但之後任何正常使用者打開那輪稽核就會替攻擊者觸發。同檔另外兩支走訪函式都有記路,只有這支沒有,是漏寫。另一條:讀範本時無條件解析 XML 且沒防呆,一筆空字串範本會讓所有人的清單頁都 500。開卡時最擔心的 XML 老問題全部實測擋住:讀本機檔案、實體炸彈、五萬層巢狀都過不了解析器(xmltodict 0.14.2 預設關實體、expat 迭代式)。整個套件零 eval/exec,三支吃檔案路徑的方法零呼叫者(死碼,建議刪)。首腦另判 runner 報的第三條「套件來源走明文 http」在範圍外且是既有 CM-1634 的重複,不另計。
📄 P1 報告
第 4 棒 H3 也掃完了(runner 沒交付,首腦補寫)。結論:任何登入者丟一份特製的流程圖給「檢查流程圖」這支 API,就能把後端一條工作程序卡住兩分鐘,連打四次整個系統對所有客戶停止回應。 這支 API 不檢查你有沒有流程範本權限、不限制圖多大、而檢查器對每個分岔點都把全部連線掃一遍。與 P1 的「惡意流程圖卡死執行緒」是同一組病,但門檻更低:不用存進去,打一次就炸。另一條:範本清單與單筆的讀取沒掛 flow_template.read 能力點,同租戶內任何登入者都拿得到全部範本的完整流程圖——這是本專案「讀取端點漏守門」第四次出現。開卡七項疑點四成立、兩確認沒問題;「凍結副本不帶租戶」查出機制(租戶靠 flush 前從登入身分自動填,沒身分就留空)並修正了 FR-087 的描述:191 筆裡只 5 筆是輪次快照、186 筆是原廠母版,回填要分兩類、根因待補查。
📄 H3 報告
第 5 棒 H4 也掃完了。真正新的一條:專案裡定義為「只能看、沒有待辦」的 viewer,其實可以把別人的稽核任務標成完成、或把流程退回上一關——完成與退回這兩支只檢查「你是不是這個專案的人」,沒檢查「這件任務是不是你的」,稽核紀錄上的經手人會變成他。守門政策檔自己寫著這是 2026-06-05 的使用者決策(任一角色皆通過),所以要先問決策者:是刻意讓所有參與者代為完成,還是漏了?runner 另報兩條首腦改判為重複:流程留言零守門(H2 已登記第 51 條,且那個檔不在本棒 scope)、compliance.projects 隔離關閉(FR-087 第 43 條甲組與 FR-083 第 10 條已記三處)。卡片八項疑點全部有答:申報給 AI 儀表板的三支查詢不是 <strong>kwargs 形狀(卡片猜錯成因),但確實零租戶過濾、全靠關著的資料庫隔離兜底;啟動流程時改寫範本 XML 的對象視呼叫者而定**(輪次走快照沒事、module-frame 匯入走母版會互相覆蓋,記非資安 bug);通知不帶留言原文、收件人從專案往下查;known_project_id 唯一來源是伺服器端解析。範圍外六條憑證有一條新型態:SMTP 寄信密碼、LDAP 綁定密碼、MinIO 金鑰、GitLab 權杖整張設定表被貼進對話紀錄,併 CM-1607。
📄 H4 報告
其餘一棒(P2)當時未掃(後已掃完,見 P2 段)。首腦讀碼時看到的疑點如下。
讀碼時看到的三個最值得先驗的疑點(未經工具驗證,行號已開檔核對):
job_evidences 連租戶欄位都沒有——猜到一個編號就能讀(留言還能寫)別家客戶的資料。與 FR-086 檔案存取同一個病。force 旗標有兩個版本:權限檢查看外層的、實際做事的 handler 讀 ctx 裡的。外層填 false、ctx 裡填 true,非管理者可能跳過「規劃就緒檢查」啟動稽核。資料庫層實況(DEV 唯讀實查):流程相關 10 張表只有 1 張隔離是開的,其餘 9 張關閉,其中 3 張連租戶欄位都沒有。FR-087 只盤了其中 3 張,另 7 張是本 arc 新增的實況。
產品裡每一個稽核專案都是照一張「流程圖」在跑:規劃 → 稽核 → 改善 → 結案。每個階段誰能按「推進」、按了之後系統要做什麼,都由「流程引擎」決定。它也負責讀寫流程圖本身(BPMN 格式的 XML 檔),以及每個任務的完成、退回、留言、證明文件。
這個 arc 要回答三個問題:① 有沒有辦法操作別家客戶(或別的專案)的流程與任務?② 有沒有辦法用一張惡意流程圖把系統弄掛?③ 流程資料在資料庫層有沒有隔離兜底?
| 表 | 隔離開關 | 規則數 | 有租戶欄 | 筆數 | 備註 |
|---|---|---|---|---|---|
compliance.flow_templates |
✅ 開 | 4 | 有 | 12 | 本 arc 唯一開的 |
compliance.workflow_templates |
❌ 關 | 4 | 有 | 17,206 | 規則寫好但關(FR-087 第 2 項);191 筆凍結副本無租戶 |
compliance.workflow_executions |
❌ 關 | 3 | 有 | 10,944 | 缺 SELECT 規則(FR-087 第 4 項) |
compliance.job_executions |
❌ 關 | 0 | 有 | 10,783 | 03:10 排程依賴 CM-1559 fail-open(FR-087 第 5 項) |
compliance.element_variables |
❌ 關 | 0 | 無 | 3,011 | 流程留言存這裡 |
compliance.job_evidences |
❌ 關 | 0 | 無 | 782 | 任務證明 |
compliance.project_audit_rounds |
❌ 關 | 0 | 無 | 41 | 有 project_id 欄但服務層從不核對 |
compliance.stage_objects |
❌ 關 | 0 | 無 | — | 階段定義(平台層,可能刻意) |
compliance.round_stage_transitions |
❌ 關 | 0 | 無 | — | 階段歷程 |
compliance.workflow_templates_trans |
❌ 關 | 0 | 無 | 5,749 | 翻譯表 |
| 順序 | 棒 | 範圍 | 檔數 | scanRoot | 為什麼獨立一棒 |
|---|---|---|---|---|---|
| 1 | H2 任務完成/回退/留言/證明 | api/flow_engine/(除範本與階段 route)+job_evidence_service+common/authz/workflow.py+證明的 domain/infra |
23 | BE repo | 門檻最低:只要登入+猜編號;守門檔檔頭自陳「原本任何 JWT 持有者猜出 id 即可跨租戶操作」,補的守門只補了寫 |
| 2 | H1 稽核階段推進與回退 | stage_advance/stage_rollback/stage_object 三條鏈+oscal_stage_* handler+registry |
21 | BE repo | 改變稽核狀態的最高權限操作;專案↔︎輪次不核對、ctx.force 雙版本 |
| 3 | P1 流程圖範本與 BPMN 解析 | jedi_flow_engine/common/+範本鏈 10 檔 |
30 | jedi monorepo jedi-flow-engine/ |
XML 解析安全判準不同(解析炸彈、深度、實體);三支吃檔案路徑的方法 |
| 4 | H3 流程範本管理 | flow_template_route+flow_template_app_service+snapshot_service+範本 domain/infra |
13 | BE repo | 惡意 XML 的入口;本 arc 唯一隔離開著的表;凍結副本無租戶的成因 |
| 5 | H4 流程執行宿主服務與接線 | 1,559 行 workflow_execution_service+DI+儀表板申報+控制項對應 |
21 | BE repo | 守門與反查鏈的實作;三支申報給 AI 儀表板的 **kwargs 查詢 |
| 6 | P2 流程執行核心 | 套件其餘 42 檔(執行/任務/變數三條鏈+plugin) | 42 | jedi monorepo jedi-flow-engine/ |
零守門是設計;要做「公開方法 vs 宿主守門」對照表 |
排序判準是「可利用門檻」不是嚴重度標籤(決策者 2026-09-12 定的判準)。一次只派一棒。合理停損點在第 3 棒之後(74 檔已涵蓋門檻最低與解析面),但沒跑完六棒不能宣稱「jedi-flow-engine 掃過了」。
接縫:H2 的守門政策檔 ↔︎ H4 的 assert_project_participant/反查鏈(同一條鏈兩端,互相允許越界讀);P1 的 BpmnUtils ↔︎ P2 的執行 service(P2 只看餵進去的是什麼,不重審解析器);H1 的 complete_main_workflow_job 住在 H4 檔內。
檔數核對:總表寫「套件 80 檔/宿主約 60-80」,實際 git ls-files 套件 72(含 3 個 .bpmn 範例)、宿主 92。六棒合計 150 檔覆蓋宿主 78+套件 72;宿主未入棒的 14 檔全是空 __init__.py 與一支 deprecated shim(common/util/workflow_project_guard.py,2 行 re-export)。
| 棒 | 卡 | 檔 | 面板 | 發現 | 報告 |
|---|---|---|---|---|---|
| H2 任務完成/回退/留言/證明 | CM-1670 | 23 | ✅ 30 票全投、verified(2 研究員全回) |
3 條(HIGH 1/MEDIUM 2)+人工 1 條(併 P1)+證偽 1 項 ⚠️ 另 6 條範圍外全是舊案(CM-1607/1608/1629/1631/1634) |
scan-H2-task-comment-evidence.md |
| H1 稽核階段推進與回退 | CM-1671 | 21 | ✅ 33 票全投、verified(2 研究員全回) |
4 條(MEDIUM 3/LOW 1);卡片兩大疑點一個「讀成立寫不成立」一個否決 ⚠️ 另 4 條範圍外全是舊案 |
scan-H1-stage-advance-rollback.md |
| P1 流程圖範本與 BPMN 解析 | CM-1672 | 30 | ✅ 9 票全投、verified(3 條皆 3:0) |
2 條 MEDIUM(runner 報 3,F2 首腦判範圍外重複 CM-1634);八項疑點五證偽、錨點答完 ⚠️ 密鑰專項零撈獲 |
scan-P1-bpmn-parsing-and-templates.md |
| H3 流程範本管理 | CM-1673 | 13 | ✅ 30 票全投、verified(10 條全 3:0;5 條降級) |
2 條(MEDIUM 1/LOW 1);七項疑點四成立二無問題一待補查 ⚠️ 24/30 票投在範圍外舊案;runner 未交付,首腦補寫 |
scan-H3-flow-template-management.md |
| H4 流程執行宿主服務與接線 | CM-1674 | 21 | ✅ 27 票全投、verified(8 條全 3:0、1 條 0:3 否決) |
runner 報 3 條;首腦改判:1 條新(MEDIUM)+2 條重複;八項疑點全答 ⚠️ 18/27 票投在範圍外;6 條憑證裡 1 條新型態 |
scan-H4-execution-host-service.md |
| P2 流程執行核心 | CM-1675 | 49 | ✅ 6 票全投、verified(候選 3 去重 2;1 條 3:0、1 條 0:3 否決) |
0 條新(runner 報 1,自標重複第 51 條);九項疑點全答(三證偽、三「機制屬實無入口」);對照表:宿主沒 import 套件 WorkflowExecutionService、JobExecutionService 接了沒人用⚠️ 密鑰專項零撈獲、無範圍外 |
scan-P2-execution-core.md |
核 stamp:verified、候選 11(去重 10)、30 票全投、9 條達標、unreviewed_candidate_sites: 0、研究員派 2 回 2。與 runner 自述一致。
逐條開檔核對(不信 runner 自述):
| 條 | 核對 |
|---|---|
| F1 證明清單 GET 無歸屬檢查(HIGH) | ✅ job_evidence_service.py:42-59 無守門,:81/:145/:168 三處有;DEV 複核 job_evidences 848 筆、RLS 關、0 規則、無 tenant 欄 |
| F8 單筆證明 GET 無歸屬檢查(MEDIUM) | ✅ :61-70 無守門;route :70-71 把單筆 dataclass 餵進 many=True 序列化器,目前靠這個 bug 擋住——修好 bug 缺口就變真外洩,兩者要同卡 |
| F9 流程留言 GET/PUT 無歸屬檢查(MEDIUM) | ✅ flow_engine_route.py:44-64/:66-121 只掛 jwt_required,route 層直接讀寫 element_variable;DEV 複核 element_variables 3,236 筆、RLS 關、0 規則、無 tenant 欄 |
證偽:is_admin 是租戶管理員? |
✅ runner 追到 jedi-iam middleware/context.py:134 is_admin=user.is_super_admin,首腦開檔屬實。common/authz/workflow.py:38 註解錯,順手併修 |
| 人工補:流程定義 GET 任何登入者可讀整份範本 XML | ✅ flow_engine_route.py:29-37 只驗登入、套件 get_workflow_template_by_uid 無租戶檢查、workflow_templates RLS 關。未經面板,併 P1(CM-1672)當錨點 |
越界檢查:範圍外 6 條逐一對照,全落在既有卡,不另計。注意力稀釋:30 票有 18 票投在範圍外,真正投在 23 檔的只有 12 票——「只有這三條」不可宣稱。
首腦改判:F9 嚴重度 runner 保留意見交決策者。首腦判維持 MEDIUM:假冒同事推播釣魚是實質衝擊,但前提與 F1 相同(需取得 UUID)而外洩內容是留言非證明本體;若決策者認為釣魚面更重可升 HIGH。
§2.9 落點:F1/F8/F9 全進 🅰 組「只驗身分不驗歸屬」(與第 34~47 條同病、修法可抄);三張表無租戶欄進 🅱 組「要先改表結構」那類(與 23/47/7 同難度)。
現況:已處理(早期未開卡,後由 FR-114 修正線照 M06 問題總表修完,1.21.0 出貨),登記總表 §3.1 第 49~51 項。
核 stamp:verified、候選 12(去重 11)、33 票全投、8 條達標、unreviewed_candidate_sites: 0、研究員派 2 回 2、耗時 4 小時。與 runner 自述一致。交付四件齊全(報告/commit 1e95823b 只含報告一檔/Notion append 含 hash 與 run ID/狀態「修正待驗證」)。
逐條開檔核對:
| 條 | 核對 |
|---|---|
| F5+F6 階段歷程 GET 零守門(MEDIUM) | ✅ stage_rollback_route.py:52-67 只掛 jwt_required、project_uid 收了沒用;套件 audit_round_app_service.py:867-887 只查存在性,回 operator/operator_nickname/reason 等 8 欄。DEV 複核:round_stage_transitions RLS 關 0 規則、21 筆/6 輪次 |
| F4 階段資訊 GET 專案↔︎輪次不核對且不擋(MEDIUM) | ✅ stage_advance_service.py:84 只用 round_uid、:118 只用 project_uid、:120 只算布林不 raise;回傳含 workflow_execution_uid(:185)。project_audit_rounds RLS 關 0 規則 |
| F8 操作者署名可自填(LOW) | ✅ stage_advance_route.py:59/stage_rollback_route.py:40 setdefault;落點 :387(BPMN 留言)、:412(討論串作者)、:450(歷程表)三處屬實;operator=curr_user 權威欄不受影響 |
| 證偽:跨專案「寫」 | ✅ 套件 _check_role(:124-134)委派 assert_project_role;七條寫入路徑 :385/:445/:476/:538/:792/:823/:847 全用 e.project_id。handler 在 :356 先於 BPMN 推進 :382,同 @transaction |
證偽:force 雙版本 |
✅ planning_readiness_checker.py:9 自陳「軟提醒非硬擋」、:13 fail-open;真正守門 :292/:303/:314 看外層 |
| runner 抓工具錯誤 | ✅ 首腦 DEV 實查 compliance.projects RLS 關但有 4 條規則(FR-087 第 43 條「規則寫好開關關」那組),project_participants 關 0 規則;全庫開 RLS 的表 33 張 |
越界:範圍外 4 條逐一對照 CM-1607/1608/1629/1631,全舊案。
首腦改判:無。F5/F6 維持 MEDIUM(前提需取得 UUID,與 H2 F1 同;但外洩的是稽核判斷的敘事文字,PM 可視需求升 HIGH)。
§2.9 落點:F4/F5/F6 進 🅰 組(「守門查對了人卻查錯了物」,與第 45 條「收了專案編號卻不用」同型);F8 進 🅶「一行能修」;project_audit_rounds/round_stage_transitions 無租戶欄進 🅱「要改表結構」。新的一條規劃相依進 🅘:本層「靠下游擋」,修 F4 時要把 advance_stage/rollback_stage 一併補歸屬檢查。
現況:已處理(早期未開卡,後由 FR-114 修正線照 M06 問題總表修完,1.21.0 出貨),登記總表 §3.1 第 52~54 項、§3.2 第 13 項(force 雙版本清理)。
runner 提的跨棒觀察採納:project_audit_rounds/round_stage_transitions「無租戶欄且無 RLS」是 FR-087 13 張表之外的死角,同型的表可能還有——已登 §3.4,母卡收口時單獨盤一次。
核 stamp:verified、候選 4(去重 3)、9 票全投、3 條達標皆 3:0、unreviewed_candidate_sites: 0、研究員派 2 回 2、耗時 7 小時 15 分(本 arc 最久,agent 12 個 1 個出錯)。與 runner 自述一致。交付四件齊全(報告/commit ebd3b1e1 只含報告一檔/append 含 hash 與 run ID wf_c14982f8-67a/狀態)。
逐條開檔核對(對 jedi HEAD 45f14ad9):
| 條 | 核對 |
|---|---|
| F1 分岔點走訪不記路+重算翻倍(MEDIUM) | ✅ bpmn_uilts.py get_next_jobs→_get_jobs_from_exclusive_gateway→get_next_jobs 成環、_get_exclusive_gateway_default_job 內再算一次;同檔 :395/:454 兩支有 visited,此支沒有。拓撲驗證器 grep `cycle |
| F3 讀範本無條件解析、空字串繞過寫入檢查(MEDIUM,可信度低) | ✅ mapper to_entity 無 try/except;repo :52/:61 if entity.xml:;宿主 module_frame_item_route.py:100 payload.get("xml", "") 無 schema。首腦實測 xmltodict.parse("") 與 " " 皆 ExpatError。runner 誠實標「寫入當下交易能否 commit」未實測 |
| F2 套件來源明文 http | ⚠️ 首腦改判:範圍外+重複。pyproject.toml 不在本棒 30 檔 scope 內;且總表 CM-1634 早已記「Nexus 私有套件庫走明文連線,26 個專案全一樣」、FR-085 C3 又撞一次。本棒是第三次撞到,佐證更強但不另計。runner 補的「monorepo poetry.lock 在 .gitignore:102、版控零 lock 檔」是新資訊,併入 CM-1634 背景 |
| 五項證偽 | ✅ 首腦重跑:XXE file:///etc/hosts 回 {'r': None};50,000 層巢狀正常回傳;三支檔案路徑方法兩 repo 零呼叫者;ET.fromstring/eval/exec 零命中 |
| 錨點:流程定義 GET | ✅ runner 答兩題:守門責任在宿主、但套件提供的 RLS「規則 4 條開關關」等於沒有;BE 呼叫者 16 處只 1 處直接是 route。DEV 複核 18,267 筆/191 筆無 tenant/RLS 關 |
版本漂移:掃描從 151c5f88 起跑,期間 jedi HEAD 移到 45f14ad9。首腦逐檔核對 P1 範圍的差異只有 logger 名稱、註解、刪 __main__ 與三個 .bpmn 範例,無邏輯變更,三條發現行號已對 HEAD。但 P2 範圍變了:plugin.py(261 行)拆成 plugin/__init__.py/assembly.py/contract.py/runtime.py/wiring.py,infra/models/__init__.py 也改了——P2 scope 已重算為 49 檔,派工前要重寫卡片(差異:plugin.py → plugin/ 五檔;另多了 api/__init__.py/api/guards.py/domain/ports.py 三支新檔——套件開始長 api 層,原 plugin.py 自陳「無 route」的前提要重驗)。
首腦改判:F2 範圍外重複(見上)。F1/F3 維持 MEDIUM。
§2.9 落點:F1 屬資源耗盡類,與 CM-1638(AI 聊天無上限)、§3.1 第 31 條(分頁無上限)同型,目前 §2.9 沒有這一組,新增 🅹「資源耗盡」;F3 進 🅹 同組(一筆壞資料拖垮查詢)+🅶(寫入端補 schema 一行);三支死碼方法進 🅶。
現況:已處理(早期未開卡,後由 FR-114 修正線照 M06 問題總表修完,1.21.0 出貨),登記總表 §3.1 第 55~56 項、§3.2 第 14 項(死碼)。
runner 未交付四件(無報告、無 commit、無 Notion 回寫、狀態未改),首腦依手冊第三節第 3 點補寫報告並核對。本 arc 第一次、全計畫第四次(C1/S7/B2/H3)。
核 stamp:verified、候選 10 去重 10、30 票全投、10 條全 3:0、5 條降級(4 條 HIGH→MEDIUM、1 條 MEDIUM→LOW)、研究員派 2 回 2、耗時 2h16m。scope 13 檔與卡片逐檔相同。
逐條開檔核對:
| 條 | 核對 |
|---|---|
F7 validate 端點可卡死工作程序(MEDIUM) |
✅ route :130-144 只掛 jwt_required;schema :28-29 無 Length;service :143-157 在 @transaction 內;驗證器 bpmn_topology_validator.py:168/:271 兩處 next(...) 線性掃;main.py:241-243 worker 4/timeout 120;config.py:105 body 50MB;全 repo 無 flask-limiter |
F10 範本讀取無 flow_template.read(LOW) |
✅ :29-45/:58-66 只 jwt_required,:20-26 無 read decorator;能力點在 04-seed-core.sql:306;同 repo project_route.py:41 有 .read 做法可抄;DEV flow_templates RLS 開、select 規則含 is_builtin OR 本租戶 |
| 範圍外 8 條 | ✅ 逐一對照 CM-1607/1608/1629/1631 與 §3.1 第 2 條,全舊案;F9 docs/claude/memory/reference_dev_login.md:11 是新位置(memory 入版控帶進來的),併 CM-1608 |
七項疑點自答(runner 沒答,首腦補):見報告 §5。重點:① 宿主 flow_templates 的 mapper 不解析 XML,壞 XML 存進去讀不會炸、發布會擋,與 P1 F3 套件側每讀必解析是兩張表兩種行為;② 內建範本守門四處呼叫無遺漏;③ DTO 無敏感欄位;④ 凍結副本不帶租戶的機制=套件範本鏈零 tenant_id 處理、靠 jedi-common db_mw.py:64 flush 前從 get_user_context().tenant_id 自動填,沒身分就留空;DEV 實查 191 筆裡 provider='snapshot' 只 5 筆、Billows-Official 母版 186 筆(jediadmin 119/blsadmin 72,2026-07-27~08-09,127 筆仍連著執行紀錄),FR-087 §5.2「191 筆凍結副本」的描述要修正,根因(當時 module-frame 匯入路徑的 context tenant 為 None)補查一個 git log -L 即可。
首腦改判:無。同意檢查員的兩處降級。
§2.9 落點:F7 進 🅹 資源耗盡(與 P1 F1/F3、CM-1638、第 31 同組,可與 P1 合一張「BPMN 輸入強固化」卡);F10 進 🅰 讀端點漏守門(第四次);F9 併 CM-1608。
現況:已處理(早期未開卡,後由 FR-114 修正線照 M06 問題總表修完,1.21.0 出貨),登記總表 §3.1 第 57~58 項。
交付四件齊全(報告/commit c6c12e68 只含報告一檔/Notion append 含 hash 與 run ID wf_ba3ef1cb-e96/狀態「修正待驗證」)——加了「開掃前先回報四件落點」那句之後這棒做滿了。核 stamp:verified、候選 9 去重 9、27 票全投、8 條 3:0、1 條 0:3、無降級、研究員派 2 回 2、耗時 4h51m;scope 21 檔逐檔相同;掃描版本 8fc8c1c1 到 HEAD 範圍內零 diff。
逐條開檔核對與改判:
| runner 報 | 首腦裁 | 理由 |
|---|---|---|
| H4-1 流程留言零守門(MEDIUM) | 重複,改列範圍外 | flow_engine_route.py 不在本棒 21 檔 scope;H2 F9 已登記為總表 §3.1 第 51 條。runner 開檔核對的內容正確,但沒對 scope 清單與既有卡 |
| H4-2 viewer 可完成/退回別人的任務(MEDIUM) | ✅ 新,登記第 59 條 | workflow_execution_service.py:655/:833 只呼叫 assert_project_participant,complete_job 本體無 assignee 比對;common/authz/workflow.py:15-16 政策自陳「任一角色(含 viewer/member)皆通過,per 2026-06-05 user 決策」;participant_enum.py:18 VIEWER = "viewer" # 純瀏覽,無待辦。產品承諾與守門政策互相矛盾,要先問決策者。runner 說批次路徑會擋 NO_PERMISSION 未核對(job_batch_complete_service.py:39 存在但本棒未讀) |
H4-3 projects RLS 關閉(MEDIUM) |
重複,改列範圍外 | scripts/sql/… 與 project_service.py 都不在 scope;FR-087 第 43 條甲組、第 5 條、FR-083 第 10 條(is_admin=True 刻意設計)已記三處;首腦 H1 驗收時已 DEV 實查 projects RLS 關但 4 條規則——runner 說「沒查線上 DB」的缺口早已補上 |
八項疑點的新資訊(runner 答得完整,兩處修正卡片的猜測):① 申報給儀表板的三支是 query_entity 形狀不是 **kwargs,卡片猜的成因錯,但零租戶過濾是真的——併入 FR-083「27 支零守門」,不另計;④ _patch_template_xml_job_uids(:429-441)寫回的是傳進來的 workflow_template:輪次流程傳快照(audit_round_app_service.py:348)沒事,module-frame 匯入傳母版(module_frame_service.py:241)多流程共用會互相覆蓋——記 §3.2 第 15 非資安 bug;⑦ 問卷 uid 進 link_task_survey(jedi-survey task_survey_service.py:140)只 verify_survey_exist_by_uid、未見租戶檢查,套件不在 scope,列 §3.4 沒讀到。
範圍外 6 條:外-1/外-3/外-4/外-5 分別落 CM-1607/1631/1629/1608。外-2 是新型態:part-verbatim-03-of-03.md:5933 把 system_configs 整張表 dump 進對話紀錄,含 SMTP Gmail 應用程式密碼、LDAP 綁定密碼、MinIO 存取金鑰、GitLab 權杖——首腦開檔(遮罩)確認四種型態都在,全部 scan 報告 grep 零命中。併 CM-1607 並在該列補這四種型態;SMTP 那把與 CM-1605「測試信端點外洩平台 SMTP 密碼」是同一組憑證。runner 另比對 .env 確認 Google 密鑰仍是活的,首腦以 .env 值前綴 grep 對話紀錄命中 11 檔屬實(CM-1631 已記「不是每套安裝各自產生」)。
§2.9 落點:第 59 條進 🅷「要先做產品決策」(政策自陳是決策)+🅰;§3.2 第 15 進非資安。
現況:已處理(早期未開卡,後由 FR-114 修正線照 M06 問題總表修完,1.21.0 出貨)。
交付四件齊全(報告/commit 31c0d7f6 只含報告一檔/Notion append 含 hash 與 run ID wf_ca839a58-ac4/狀態「修正待驗證」)。核 stamp:verified、候選 3 去重 2、6 票全投、1 條 3:0、1 條 0:3、無降級、研究員派 2 回 2、耗時 3h21m;stamp 內 scope 49 檔;掃描版本 ac9c152,掃描期間 jedi HEAD 走到 677f20f(task-platform 的改動),jedi_flow_engine/ 零 diff。
runner 唯一報的一條自標重複,首腦同意:P2-1 流程留言零守門=H2 第 51 條(決策者 2026-09-13 已裁升 HIGH)。本棒的價值是從套件側證實 element_variable_service.py:26/:50 同樣零檢查——不存在「套件有擋、宿主漏傳」的可能,守門只能加在主專案 app service 層。這句已補進總表第 51 條。
首腦獨立開檔核對四項,全部屬實:① 主專案六個目錄 grep 零 import 套件的 WorkflowExecutionService——卡片寫「complete_job/revert_job 零授權檢查是設計如此、宿主包一層」,實況是宿主整支重寫了自己的,套件那 13 支公開方法目前沒有任何外部入口;② JobExecutionService 在 di_containers/flow_engine/workflow_excution_containers.py:113 建了 provider,全 codebase 零取用——接好沒人用的插頭,6 支方法零守門零租戶檢查,哪天接上就是現成的無守門端點,登記 §3.2 第 16 為未來陷阱;③ plugin/assembly.py:39 建的 blueprint 沒掛任何 resource,api/guards.py 整支只有一支 runtime(),名字叫 guards 但不是守門,與主專案 common/authz/workflow.py 不構成兩套並存;④ domain/ports.py 兩張插槽是讀設定與寄信,不是權限判斷,沒接不會變放行。
被否決的那條反而有用:研究員報「element_variables 沒掛租戶 mixin、比姊妹表危險」,三個檢查員以出貨基線 schema 一致否決——因為姊妹三張的隔離開關也全是關的,反差不存在。這坐實「四張流程表資料庫層一道隔離都沒有」:workflow_executions/job_executions/workflow_templates 三張 FR-094 已接(CM-1770/1771/1772),element_variables 連租戶欄都沒有,只能靠程式層守門,即第 51 條那批。
兩處 runner 沒做、首腦記下:DB 隔離狀態是讀 scripts/init/02-schema.sql 不是 DEV 實查(runner 自陳)——與首腦 H2/H3 的 DEV 實查結果一致,不需重查;工具沒留逐檔閱讀帳本(coverage.research 空),「49 檔只有這一條」的信心停在中等,但卡片九項疑點無一「沒讀到」。
無新發現,無需修正。六棒收口:母卡 append 六棒總表;SUMMARY 等決策者下令。
現況:已處理。 對應 docs/security-report/M06-flow-engine.md:24 件中 23 件已修(隨 1.21.0 出貨,含 viewer 可代完成他人任務/回退流程的守門、凍結副本、惡意流程圖卡死執行緒等)、1 件裁定刪除(M06-14+16 三支接收路徑,CM-2215)。
~/Projects/Jedicogy/module/jedi-python-package/jedi-flow-engine/(scanRoot 指此子目錄,與 FR-086 B1 同做法)api/flow_engine/、app/flow_engine/、domain/flow_engine/、infra/flow_engine/、di_containers/flow_engine/、di_containers/dashboard_apis/flow_engine.py、common/authz/workflow.py、app/flow_control/service/oscal_stage_*.pyworkflow_templates/workflow_executions/job_executions 三張表與 191 筆無主凍結副本)、FR-083 D2(儀表板 27 支零守門)、FR-079 F13(**kwargs 掉租戶過濾)、FR-086(四層全空的檢查清單).claude/skills/security-scan-lead/SKILL.mdsecurity-scan-consolidated/FR-075/handoff/security-scan-STATE.md以下全部由 build 掃資料夾產生,新增檔案重 build 即自動出現。標題連結指向渲染後的 HTML,md 連向源檔。
| 文件 | 類型 | 標題 | 最後更新 |
|---|---|---|---|
| scan-H1-stage-advance-rollback / md | 盤點證據 | FR-088.2 H1:稽核階段推進與回退——資安掃描報告 | 2026-09-12 |
| scan-H2-task-comment-evidence / md | 盤點證據 | FR-088.1 H2:任務完成/回退/留言/證明——資安掃描報告 | 2026-09-12 |
| scan-H3-flow-template-management / md | 盤點證據 | FR-088.4 H3:流程範本管理——資安掃描報告 | 2026-09-13 |
| scan-H4-execution-host-service / md | 盤點證據 | FR-088.H4 掃描報告:流程執行宿主服務與接線(主專案 flow_engine) | 2026-09-13 |
| scan-P1-bpmn-parsing-and-templates / md | 盤點證據 | FR-088.3 P1:BPMN 流程圖解析與範本讀寫——資安掃描報告 | 2026-09-13 |
| scan-P2-execution-core / md | 盤點證據 | FR-088.6 P2:流程執行核心(套件本體 49 檔)——資安掃描報告 | 2026-09-13 |
由新到舊。每份是某一棒次交接當下的完整現況快照,看某個時間點「當時知道什麼」請從這裡進。
| 日期 | 文件 | 標題 |
|---|---|---|
| 2026-09-14 | 2026-09-14-FR-088-SUMMARY / md | FR-088 流程引擎(jedi-flow-engine)資安掃描 — 收口 SUMMARY |
卡片內容(決策紀錄、驗收條件)以 Notion 為準,本頁只記座標。
| 關係 | 卡號 | 標題 | 狀態 |
|---|---|---|---|
| 母案 | CM-1669 | FR-088 流程引擎(jedi-flow-engine)資安掃描(六棒 150 檔,只掃不修) | — |
| 子卡 | CM-1670 | H2 任務完成/回退/留言/證明(23 檔,BE repo) | Done |
| 子卡 | CM-1671 | H1 稽核階段推進與回退(21 檔,BE repo) | Done |
| 子卡 | CM-1672 | P1 流程圖範本與 BPMN 解析(30 檔,jedi monorepo) | Done |
| 子卡 | CM-1673 | H3 流程範本管理(13 檔,BE repo) | Done |
| 子卡 | CM-1674 | H4 流程執行宿主服務與接線(21 檔,BE repo) | Done |
| 子卡 | CM-1675 | P2 流程執行核心(42 檔,jedi monorepo) | Done |