找到漏洞的 agent 不能自己說算:security-audit-skill 派全新驗證代理專門推翻結論,推不翻才進 confirmed 清單

目錄
共 11 個章節
「找到漏洞的 agent 自己說算」為什麼是資安稽核最常出錯的一步
同一個 AI 代理(agent,會自己開子流程、跑指令的 AI 助手)先找出問題,再自己蓋章說這是漏洞,中間沒有其他人插手,這就是資安稽核最常見的翻車現場。因為沒有人在中間插嘴,報告裡往往塞滿聽起來很嚴重、實際打不穿的項目,也就是誤報。你拿著這樣一份清單去開會,心裡其實也不敢掛保證。

問題出在,找漏洞和判斷漏洞是兩種相反的心態。找的人得不斷假設「這裡可能有問題」,驗證的人卻要想辦法證明「這裡其實沒事」。同一個 agent 兩件事都做,它會順著自己剛剛的推論繼續找支持的證據,而不是回頭推翻自己;這種傾向叫確認偏誤,人類工程師也會犯,但 AI 會把它規模化,一次吐出幾十條看起來都有道理的項目。於是工程師逐條比對後只修三條,其餘當雜訊關掉,幾次之後連報告都懶得打開了。
把驗證拉成獨立一關,讓別人來推翻
Cloudflare 開源的 security-audit-skill 針對的正是這件事。它是一套給 AI 代理照著跑的稽核技能包,在 GitHub 上累積約 5 萬顆星(2026-10-28 查詢)。它把稽核拆成六個階段,第三階段叫候選驗證,做法是把每一個候選漏洞交給一個全新的驗證代理,並且明文規定它的任務是「想辦法推翻它」,而不是「確認它」。關鍵就在「全新」兩個字:這個代理沒參與前面的搜尋,所以不會捨不得別人找到的線索。
換句話說,這套流程允許 agent 說「我不知道」,而不是逼它在有和沒有之間硬選一個,三種結論的分法後面的章節有對照表。官方原則還補了一條:縱深防禦的缺口不算漏洞,A 層已經擋住,B 層沒做只是加固建議。相較之下,一般掃描器只要跟檢查表不一樣就打勾,誤報當然清不完。
派一個沒參與搜尋的代理來推翻:對抗式驗證實際怎麼運作
驗證代理必須是「全新」的,這不是再掃一次,而是刻意的角色對調:搜尋代理負責找出可疑的地方,驗證代理負責證明這裡沒事。所以第三階段把候選清單交給另一批代理,任務寫得很直白,想辦法推翻它。

驗證代理會一路追問:這個輸入真的能從外部送進來嗎?中間有沒有既有的檢查把它擋掉?有沒有具體的受影響對象,例如某位使用者的資料或某個權限?追不到這些,候選就會被推翻。Cloudflare 在專案裡講得很清楚:只有真的跨過信任邊界、具備明確受影響主體與實際觀察結果的候選,才算確認的漏洞。
三種結論各自代表什麼
驗證跑完只會落在三種狀態,報告照這三類分開呈現,不讓讀者自己猜。
| 結論 | 代表什麼 | 報告怎麼呈現 |
|---|---|---|
| confirmed | 有完整來源追溯,而且真的觀察到結果 | 列入主要發現,附上嚴重度 |
| needs_validation | 有一個明確但還沒解開的事實,例如缺沙箱能力 | 獨立一份清單,標明還缺什麼 |
| rejected | 已經被推翻的候選 | 保留紀錄,說明被推翻的理由 |
嚴重度只在 confirmed 出現,理由是誠實:嚴重度是「可能性乘上影響」的估算,必須有具體攻擊路徑與受影響資產才站得住腳;needs_validation 是「知道這裡有疑點,但還缺一塊拼圖」,貼上分數只是誤導,所以留白。rejected 也不是直接丟掉,而是留下被推翻的理由,下次執行才不會繞回同一個地方。第四與第五階段每次替換資料後會跑 validate-findings.cjs 檢查格式,但它只管欄位有沒有填對,判斷對不對仍由人負責。
實機看一遍:驗證跑完會留下哪幾個檔案、哪幾行結論
跑完一輪,你得到的是一個資料夾 ~/security-audit-skill/<repo-name>/run-<N>,內含 architecture.md、coverage-ledger.json、findings.json、REPORT.md、FINDINGS-DETAIL.md、NEEDS-VALIDATION.md。run-<N> 不覆寫舊結果,可逐輪對照兩份 findings.json,官方預設就是把它當可累積的紀錄。

第一階段留下兩份檔案:architecture.md 是 agent 畫出的系統地圖(進入點、信任邊界、對外介面),等於幫沒有規格書的老專案補一份架構摘要;coverage-ledger.json 是「確定性覆蓋」清單,把系統切成可獨立檢查的單位,第二階段搜尋代理照它派工。判斷這一輪查了多少,看覆蓋清單比看結論檔準。
findings.json 裡一筆紀錄長什麼樣
每筆紀錄都屬於三種結論之一,確認的紀錄要寫清楚是哪個檔案、哪一行、什麼輸入跨過哪條信任邊界,以及實際觀察到的結果。格式由 report-schema.json 把關。REPORT.md 是摘要、FINDINGS-DETAIL.md 是逐筆細節、NEEDS-VALIDATION.md 是給人看的待辦清單,可交給原開發者、外包商或當下一輪起點。
「目標中性」指只描述觀察到什麼,不替對方假設威脅模型,也不把「跟檢查表不一樣」打成漏洞;縱深防禦缺口(A 層已擋、B 層沒做)寫成加固建議,不算 confirmed。
另有兩道自動檢查:validate-coverage-ledger.cjs 管覆蓋清單、validate-findings.cjs 管結論檔,兩支都是零依賴的 Node.js 腳本,只驗欄位與格式;對錯交給第五階段,由沒參與搜尋的新代理重新推導每筆結論。覆蓋清單建完與每次更新後各跑一次,結論檔在第四階段輸出後、第五階段每次替換後各跑一次;資料有實質替換時再找另一個獨立驗證者,避免同一人既改又審。整個技能包是 15 份 Markdown 加 1 份 JSON schema,搭配 4 支測試與驗證腳本。
替代方案有限公司觀點:驗證代理推不翻的東西,才是你要自己盯的地方
驗證代理沒參與搜尋,任務是想辦法推翻每一筆結論;它推不翻,不代表系統沒問題。

技能包規定,A 層防線已經擋住的攻擊,B 層就算沒做到,也只能寫成加固建議,不能列為漏洞。拿到報告時,confirmed 清單可以當成修補的優先順序;被降級成建議的項目,要由你自己判斷值不值得花工。
適合交給驗證代理,與它幫不上忙的事
| 交給驗證代理 | 驗證代理幫不上忙 |
|---|---|
| 候選漏洞是否真的跨過信任邊界 | 跨過去之後的商業損失有多大 |
| 結論有沒有來源追溯、能不能重現 | 沒人讀報告時,風險由誰決定接受 |
| 覆蓋清單有沒有漏掉整個區塊 | 正式環境的實際流量與營運例外 |
| 輸出格式與欄位是否正確 | 你要現在修,還是排進下一季 |
覆蓋率要如實說明:Cloudflare 在專案 README(2026 年)寫明,單次執行大約只找到重複執行總量的一半漏洞,這是原廠自己的測試,不是行業統計,所以跑一輪不等於已經掃乾淨。
成本也是同樣的邏輯:這套流程以代理呼叫次數作為預算,先保留評論者和驗證所需的額度,剩下才派搜尋代理;額度不夠不會勉強執行,而是把該次執行標記為 incomplete,代表覆蓋不完整。
我們的觀察是,台灣多數中小企業沒有專職資安人力,問題通常不在工具不夠強,而在報告產出後沒有人讀。建議把它綁在交付節點上:外包驗收前、老系統交接前各跑一輪,讓 confirmed 清單成為驗收附件。它把「平時就有紀錄」的成本壓到接近零,但「這個風險要不要接」仍然要由人判斷。
台灣團隊怎麼用:把 confirmed 清單變成一張可以交差的紙
上一章談到 incomplete 標記怎麼讀,然而更現實的問題是:報告跑完之後,誰會打開它?比較務實的做法,是把 confirmed 清單當成一張可以交差的紙。所謂交差,是有具體對象要說服,可能是業主、主管,或半年後接手的人;畢竟沒有對象的報告,通常不會有人讀。

最常見的交差場合是外包驗收。你可以請外包商在交付前跑一輪,或自己跑,接著把 confirmed 清單附在驗收單後面。這樣一來,討論會從「我覺得怪怪的」變成「這三筆有來源追溯,請說明」,爭點因此具體化,不再只靠驗收人員的經驗去猜。
換成老系統交接,壓力更大一些。很多台灣企業的老系統沒有規格書,前任工程師離開後,接手的人只能從程式碼慢慢推。因此讓它先產出 architecture.md 與覆蓋清單,至少知道邊界在哪、哪些入口查過。不過架構圖是 agent 讀出來的,仍要人工核對,不能直接歸檔當正式文件。
至於上線前,關鍵在把靠人記得的問題交給清單。例如測試資料或金鑰有沒有被帶進版控,這類事每次上線都有人提醒,卻每次都有機會漏掉。所以寫進覆蓋清單、讓每次執行重新確認,會比依賴資深同事的記憶可靠。
三件不該期待的事
不過這套做法有明確的天花板。它不能取代滲透測試,兩者方法與深度不同;一輪跑完的覆蓋率本來就不完整。它也不是零人力方案,報告還是要有人讀、有人決定風險要不要接。更關鍵的是不能在正式環境直接跑,技能要求唯讀檢視與沙箱隔離,缺少沙箱只能把該項列為待驗證。
所以把它定位成「交付前的自我檢查」,會比「資安部門的替代品」貼近現實;團隊只要有一個人願意看報告、願意把清單附上去,流程就成立。
常見問題 FAQ
Q:這跟一般講的漏洞掃描器差在哪?我需要另外裝什麼嗎?
它本身不是掃描器,而是一份給 AI 代理照著跑的稽核作業手冊,加上兩支檢查輸出格式的 Node.js 腳本。安裝只要在專案裡下一行 npx skills add 指令,之後直接在專案裡叫 agent 做「security audit this codebase」就會觸發。差別最大的是結論怎麼來:一般掃描器是工具說了算,這套規定每個候選漏洞都要交給「沒參與搜尋」的全新驗證代理推翻一次,推不翻才進 confirmed 清單。它也要求只確認真的跨越信任邊界的事,A 層已經擋住的縱深防禦缺口不算漏洞。跑完會產出 REPORT.md、FINDINGS-DETAIL.md 等檔案。
Q:讓 AI 翻我們的程式碼,會不會亂跑、動到正式環境?
技能對這件事寫得很硬。原始碼檢視是唯讀的;要跑目標端的建置、測試或模糊測試,只能在作業系統層強制的沙箱裡,而且要同時滿足沒有對外網路、空環境啟動、目標與工具鏈唯讀、被測程序只能寫自己那個 scratch/ 目錄,並限制 CPU、記憶體、程序數與執行時間。做不到這些控制就不能執行目標程式碼,要把「缺沙箱能力」寫成 needs-validation 的阻礙。它另外明文禁止對正式站點或共用服務探測、對正式程序做可用性測試、改動發佈流程。每個代理的寫入都鎖在自己的目錄,要留下的檔案由父代理逐檔驗證後才搬進 artifacts/。
Q:跑一次就能說「我們檢查過了」嗎?找到的漏洞可以直接信嗎?
不行。官方寫明單次執行大約只找到重複執行總量的一半漏洞。所以它用「代理呼叫次數」當預算,要求先保留驗證與評論者的額度再派搜尋,額度不夠就不派,並把該次執行標記為 incomplete,不准宣稱完整覆蓋。跑完還是要有人看報告,不能把清單當成保證。
📩 有任何問題或需要協助,歡迎聯絡我們:[email protected]
Related





