Swarm audit
盤點 → 分割成區段 → 每個區段一個 worktree 和一個審計代理 → 每個代理向協調器報告經過驗證的發現 → 對所有發現進行鏈式審計 → 一份合併報告。協調器是您開始所在的 worktree。在繼續操作之前向用戶顯示每個工件;由他們決定範圍和分組。
0. 預檢
在執行任何其他操作之前,先解決三件事。在單一 AskUserQuestion 呼叫中提問每個未解決的問題(如果沒有問題工具則直接提問),然後停止直到用戶回答。
威脅模型。 尋找 **/THREAT_MODEL.md,跳過供應商和已安裝的依賴目錄。如果存在一個沒有模板 <…> 佔位符的檔案,則使用它。否則提問,除非用戶已經要求快速執行:
- 先建立威脅模型(建議):每個區段審計員和批評者都會使用其控制和範圍外列表,這能減少整個群組的誤報並發現業務邏輯錯誤。前期需要幾輪提問;後續的審計可以重複使用。
- 不建立直接快速執行:沒有提問也沒有威脅模型;區段審計員僅根據盤點結果和程式碼進行工作。這是查看群組發現結果最快的方式;但預計會有更多雜訊。
選擇建立時,在協調器中透過 Skill 工具執行此插件附帶的 security-audit 技能,僅請求威脅模型,並在步驟 1 之前等待 THREAT_MODEL.md 產生完成。
分割策略。 如果參數包含 --by-group [N] 或 --by-theme,則使用該策略。否則提問:
- 按主題(建議):區段根據程式碼的功能進行分組(驗證、帳戶、付款、訂單、管理員,每個第三方整合一個區段)。每個審計員都能看到完整的流程,因此可以發現跨越多個入口點的錯誤。區段大小不一。
- 按群組:按照原始碼順序將入口點分為約 N 個的固定大小群組(詢問 N 的值,預設為 25)。每個審計員的工作量均等,無需判斷,但一個流程可能被切分到兩個區段;鏈式審計(步驟 6)可以部分恢復此問題。
範圍。 如果用戶未指定,詢問要涵蓋哪些服務、目錄或入口點類型,以及要排除哪些內容。
1. 盤點入口點
入口點是任何外部輸入到達程式碼的地方:HTTP 路由、GraphQL/RPC 處理器、webhook、佇列和事件消費者、讀取外部資料的排程任務、CLI 指令、檔案或上傳處理器、用戶端訊息、深層連結或 IPC 處理器。
- 使用程式碼庫語言的解析器(其編譯器或語言伺服器 API,或 tree-sitter)來尋找它們,而不是正則表達式:註冊跨越行數並接受陣列。將腳本保存在暫存區以便可以重新執行。
- 每個入口點記錄:種類、名稱或方法 + 路徑、誰可以訪問(公開、已登入、管理員、內部、簽名 webhook)、防護(驗證、MFA、驗證碼、速率限制、輸入結構、簽章檢查)、處理器、整個中介軟體、裝飾器、過濾器或攔截器鏈、
file:line。 - 容易遺漏的:
- 在前綴下註冊的巢狀路由器、控制器或處理器群組,以及在傳入的物件上註冊的輔助函數
- 在輔助函數內部全域註冊的處理器:沒有前綴
- 從較早的前綴層級或全部捕獲註冊繼承的中介軟體、過濾器或防護
- 同一個處理器群組被註冊兩次:列出一次,註明別名
- 僅限環境的入口點(暫存、除錯、功能標誌):標記它們
- 依賴項註冊的入口點(驗證伺服器、管理面板、健康檢查、任務儀表板):讀取套件原始碼,手動添加它們
- 找出缺少的內容:檢查用戶端程式碼(Web 應用程式、行動應用程式、代理、其他服務)以尋找它發送的每個路徑或訊息,並列出在頂層註冊的所有內容。詢問用戶要添加哪些;說明您遺漏了哪些以及原因。
- 將盤點結果寫入協調器 worktree 中的
entry-points.md(或用戶指定的名稱)。
2. 分割成區段
- 按主題:根據程式碼的功能分組,而不是按大小,並且永遠不要在同一個區段中混合兩個信任邊界(公開、合作夥伴、內部、工作者)。將對一個審計員來說太大的主題進行拆分。
- 按群組:按順序將盤點結果切割成約 N 個的群組;當一個檔案的入口點僅改變群組幾個數量時,將它們保持在一起。
- 顯示建議的分割(名稱、計數、一行內容描述、判斷說明)並等待批准,然後將其寫入盤點檔案。
3. 每個區段一個 worktree
從協調器的當前提交切割每個區段的 worktree,這樣每個區段審計的都是用戶正在處理的程式碼。當 command -v mori 能找到它時使用 mori,否則使用純 git:
| mori | git | |
|---|---|---|
| 建立 | mori new sec-audit-NN-<name> --from <current branch>;它會列印 worktree 路徑(在 ~/.mori/worktrees/<repo>/ 下)— 記錄它 | git worktree add ../<repo>-sec-audit-NN-<name> -b sec-audit-NN-<name> |
| 依賴項 | 如果倉庫的 .mori.json 有 post_create 步驟,則由其安裝;否則自行安裝 | 自行安裝 |
| 移除 | 檢查 mori list --json 中的 dirty,然後 mori remove <branch> -f;如果分支仍然存在則刪除它 | 檢查其中的 git status,然後 git worktree remove <dir> 和 git branch -D <branch> |
在分離的 HEAD 上,使用 git(git worktree add <dir> -b <branch> HEAD)。在後台建立 worktree。
- 複製到每個 worktree:
AUDIT_SCOPE.md(區段的表格、欄位註解、「僅審計這些入口點」)、完整的盤點結果,以及如果威脅模型已建立但尚未提交,則在相同路徑複製一份。 - 在協調器中建立收件匣:
<orchestrator>/.security-audit/swarm/<section>/。 - 要重做分割:按上述方式移除舊的 worktree 及其分支(切勿強制移除含有您尚未查看的變更的 worktree),然後重新建立。
4. 平行執行區段審計
將一個簡要說明寫入暫存區,並為每個區段生成一個指向其 worktree 的背景代理。簡要說明必須包含:
- 僅在 WORKTREE 中工作;讀取其代理指令(
CLAUDE.md、AGENTS.md)。WORKTREE 外部的唯一寫入是到 INBOX(協調器中該區段收件匣的絕對路徑)。 - 使用此插件附帶的
security-audit技能(或用戶指定的其他技能),透過 Skill 工具,範圍限定為@AUDIT_SCOPE.md;在快速執行中,告知它這是快速執行,因此它永遠不會停下來提問。如果沒有威脅模型:從入口點到接收器追蹤每個輸入,標記file:line,證明它在每個控制之後都是可到達的,丟棄任何不可到達的內容。 - 如果有威脅模型:在追蹤之前完整讀取它;使用其入口點、控制和範圍外列表;切勿改寫它。快速執行:沒有威脅模型,不要建立一個。永遠不要提問。
- 每個候選項目都交給一個新的批評者子代理,該子代理假定為誤報;如果無法生成,則自行批評並對每個發現進行說明。
- 關鍵/高:一個通過真實入口點的失敗測試,使用倉庫的測試執行器執行,留在樹中。
- 一旦批評者返回,立即將每個發現報告到 INBOX,每個發現一個檔案(
NN-<slug>.md),這樣即使代理的輸出被截斷也不會遺失。格式如下。 - 同時報告被阻擋的候選項目:一個到達接收器但需要區段無法提供的內容(id、token、受害者操作、洩漏的值、競爭條件)的流程。使用
status: blocked並精確命名缺少的內容;其他區段可能可以提供。 - 同時將區段報告寫入
WORKTREE/.security-audit/<section>-<date>.md。 - 嚴格規則:遵循倉庫的安全規則;沒有遷移或資料庫腳本,沒有 git 寫入,沒有呼叫外部服務。
- 最終訊息:判決行,每個發現一行,發送到 INBOX 的檔案數量,未驗證的項目,以及審計技能是如何被呼叫的。
發現檔案格式:
---
id: <section>-NN
status: validated | blocked
severity: critical | high | medium | low | info
critic: independent | self
entry_point: <method + path or handler name>
needs: <what the attacker must have before: account type, id, token, victim click, timing>
gives: <what the attacker has after: leaked value, write access, session, money, code execution>
test: <path or none>
---
一行聲明。
追蹤:來源 `file:line` → … → 接收器 `file:line`。
再現:在程式碼區塊中給出精確輸入(請求、訊息、檔案)。
檢查的控制項:查看了哪些以及為什麼它們無法阻止此問題。
needs 和 gives 是鏈式審計進行連接的關鍵:請具體地寫明(「受害者的訂單 ID」,而不是「一些資料」)。
您可以自行內聯審計一個區段。預計並發子代理限制會阻止一些批評者。
5. 鏈式審計前重新檢查
當每個區段代理完成後,讀取收件匣並將檔案計數與每個代理的最終訊息進行比較。然後自己執行一個全新的批評者,針對:
- 任何
critic: self的高或關鍵發現 - 任何標記為暫時、有條件或「依賴於 <其他服務>」的發現:如果您有該服務的程式碼,請讀取它並解決問題。服務之間邊界上的錯誤是每個區段單獨遺漏的。
使用批評者的嚴重性更新發現檔案,並在 was: 行中保留原始內容。
6. 鏈式審計
在協調器中對整個收件匣進行最後一次審計,手邊要有盤點結果和威脅模型(如果有的話)。內聯執行,或作為一個帶有完整收件匣簡要說明的代理執行。
- 去重。 將具有相同根本原因(相同的接收器和缺少的控制)的發現合併為一個,列出命中它的每個區段和入口點。一個錯誤的兩個入口點是一個具有更大影響範圍的發現,而不是兩個發現。
- 連接。 對於每對發現,檢查一個發現的
gives是否滿足另一個發現的needs,包括blocked候選項目。同時尋找常見的提升路徑:- 資訊洩漏(id、email、token、內部 URL)→ 需要的 IDOR、帳戶接管或 SSRF
- 用戶列舉 + 缺少速率限制 → 憑證填充或 OTP 暴力破解
- 自 XSS 或 HTML 注入 + CSRF 或登入 CSRF → 受害者上的儲存型 XSS
- 開放重定向 + OAuth 或魔法連結流程 → token 竊取
- 大量賦值或弱驗證 + 下游的特權消費者(工作者、管理員視圖、webhook)
- 競爭條件 + 餘額、優惠券、限制或一次性操作 → 重複獲利
- 兩個低影響的業務邏輯漏洞結合起來轉移資金或繞過限制
- 證明每個鏈。 從頭到尾追蹤它,每個環節都有
file:line以及每一步的精確輸入。程式碼中不存在的環節就不是鏈:不要發明一個,也不要計算一個需要任何發現或公開操作都未提供的先決條件的環節。 - 使用一個全新的子代理批評每個鏈,並行進行。它假設這些步驟在實踐中無法連接(不同的用戶、不同的會話、過期的 token、順序問題、某個步驟已被另一個控制修復),並返回鏈的嚴重性:最終影響 × 所有步驟一起發生的可能性,或「清除」。
- 測試每個關鍵或高鏈,使用一個失敗的測試,該測試透過真實的入口點驅動每個步驟,在協調器 worktree 中進行。
- 將每個鏈以發現格式寫入
<orchestrator>/.security-audit/swarm/chains/NN-<slug>.md,並帶有links:列出發現的 ID。同時保留其組件發現。
7. 合併報告
在協調器中寫入 .security-audit/<scope>-combined-<date>.md:
- 判決行,包含去重後的計數,鏈單獨計數(「3 個鏈,2 個提升嚴重性」)。在快速執行中,以
security-audit技能的references/REPORT_FORMAT.md中的快速執行行開頭。 - 首先是鏈:步驟作為編號列表,包含輸入和
file:line、最終影響、鏈式審計前後的嚴重性、批評者、測試路徑。說明哪個單一修復會中斷每個鏈。 - 關鍵/高級別詳細報告:使用精確輸入再現、帶有
file:line的追蹤、影響和先決條件、修復、批評者、測試路徑以及測試未證明的內容。 - 中級別表格,低級別列表(折疊),沒有被解鎖的阻擋候選項目(折疊:它們是線索,不是發現)。
- 跨區段的模式。
- 覆蓋範圍差距和未驗證的項目(被截斷的代理、收件匣計數不匹配、生產配置、第三方行為、自我審查的批評者)。
- 區段表格,包含每個 worktree 中的報告路徑。
不提交任何內容。以鏈和關鍵/高級別表格引導聊天摘要,並說明首先交付哪個修復:優先選擇能中斷最多鏈的那個。