把整個程式庫交給安全 Agent,幾小時後收到十幾個「高風險漏洞」,最危險的不是它什麼都沒找到,而是你無法分辨哪些真的跨越信任邊界、哪些只是缺少最佳實務、哪些還差一個部署事實。Cloudflare Security Audit Skill 想解決的,正是「Agent 說它找到了」和「證據足以成立」之間的落差。
這個專案在 2026 年 9 月突然受到關注:RepoRadar 的9 月 16 日每日快照記錄當次統計日增加 1,434 顆星。不過星數只是需求與討論熱度,不是漏洞發現率、誤報率或安全成效。Cloudflare 公開的也不是完整生產 Harness,而是一個可安裝的單一 Repo 起點;真正重要的是它能不能把審計範圍、候選發現、反證與最後報告鎖進可檢查的契約。
這篇專為第一次評測安全 Agent 的開發者寫。我們會鎖定官方 Repo 的 c1c8a8c1471069fb0e188eeaff69b8e8db6564a8 commit,先做零金鑰 preflight,再設計三個故意測例:一個應成立、一個應被反證、一個必須保留待驗證。本文提供的是可供實作的隔離評測藍圖,不是已封裝、可一鍵重播的 benchmark;完整重做仍要固定 fixture 原始碼與答案、runner/sandbox、完整 prompt、模型版本、scorer 與檔案 hash。本文沒有實際執行三個測例,也不把預期 verdict 寫成 AlphaLab 成績。
先說結論:安全審計可信度,不等於 Agent 寫得多
先記住本文的錨點:
審計可信度 = Coverage Ledger(覆蓋帳本)× Fresh Verifier(獨立反證)× Schema Gate(機械驗證)。
Prompt 可以引導調查;證據契約才決定能不能下結論
三項少一項都不夠。沒有 Coverage Ledger,你不知道哪些入口與邊界根本沒看;沒有 fresh verifier,找出候選的人也同時當裁判;沒有 schema gate,最後的報告可能把「尚缺部署資訊」偷換成「高風險漏洞」。反過來說,JSON 通過 validator 只證明格式與部分狀態一致,並不會自動證明漏洞是真的。
Cloudflare Security Audit Skill 是什麼?它不是完整 Harness
官方 security-audit Repo 是一套給 coding agent 使用的 Skill:核心是 SKILL.md、多份攻擊面 companion 文件、JSON Schema,以及兩個零外部套件的 Node.js validator。官方 Repo 提供多 Agent 工作流、角色與產物契約;是否真的以 fresh owner 分派、隔離寫入並強制 OS sandbox,取決於宿主 Agent 平台與外層 Harness。Repo 本身不提供容器、sandbox launcher、持久化資料庫、模型計費、排程或跨 Repo 去重服務。
如果你還不熟 Skill 的角色,可以先讀 AlphaLab 的Agent Skill 與 SKILL.md 教學;如果連 Agent、工具、狀態與停止條件如何組成迴圈都還模糊,先補AI Agent Harness 的白話原理。最簡單的分法是:Skill 提供提示、角色與產物契約;Harness 才負責把執行、隔離、狀態、重試與成本真的接起來。
為什麼 Cloudflare 部落格寫七階段,現在 README 卻是六階段?
兩者不是同一份公開 Artifact。Cloudflare 在 2026 年 6 月 18 日發表的漏洞 Harness 長文用七階段描述內部流程,也提到三個 reconnaissance Agent;同日公開 Repo 的 README 已經是六階段,沒有內部 ingest API。2026 年 9 月的公開版本又加入四個基線 reconnaissance 角色、Coverage Ledger 與更嚴格的模式/安全契約。本文只以 pinned commit 的六階段公開 Artifact 為準,不能把部落格與 Repo 拼成一版操作手冊。
官方也明確區分:這個公開 Skill 是 single-repo starting point,Cloudflare 內部後來擴成跨 Repo、可持續跑的 fleet harness。公開長文的內部掃描漏斗與「單次約找到重複執行總量的一半」都是 Cloudflare 自行回報,而且沒有公開標註答案的完整資料集;它們適合形成假說,不足以替你自己的 Repo 宣告召回率。
Cloudflare Security Audit Skill Step 0:先完成零金鑰 preflight
不要在日常開發帳號、公司 VPN 或掛著雲端憑證的 shell 直接安裝。先建立 disposable VM/container 或專用低權限帳號,只開 GitHub 與套件來源給「取得與審查」階段;不掛載 SSH key、瀏覽器資料、雲端設定、production .env 或使用者家目錄。這不是多餘儀式:Skill 之後可能要求 Agent 執行目標的 build、test、parser、browser 或 fixture,而待審程式本身就是不可信輸入。
先用唯讀方式鎖版本、確認工作樹與列出敏感執行點:
git clone https://github.com/cloudflare/security-audit-skill.git
cd security-audit-skill
git checkout c1c8a8c1471069fb0e188eeaff69b8e8db6564a8
git rev-parse HEAD
git status --short
find skills/security-audit -maxdepth 1 -type f -print | sort
rg -n 'exec|spawn|network|sandbox|needs_validation' \
skills/security-audit
官方 README 展示的 remote URL 指令會追蹤當下 main,所以只適合辨認 current-main 安裝入口,不能當本文 pinned commit 的可重現步驟。真正評測時,先離開 source clone,在另一個 disposable project 中,用你已審查並固定的 Skills CLI 版本,從 detached local checkout 安裝:
cd /path/to/disposable-agent-project
SKILLS_CLI_VERSION='REPLACE_WITH_REVIEWED_VERSION'
npx --yes "skills@${SKILLS_CLI_VERSION}" add \
/absolute/path/to/security-audit-skill \
--skill security-audit
npx 仍會下載並執行 CLI;先依你的供應鏈政策決定固定版本,再記錄 CLI、source SHA 與安裝後完整 Skill tree hash,確認仍等於審過的 c1c8a8c…,不一致就停止。不要加 --global 污染日常 Agent 設定。若要先掃 Skill 與 MCP,可搭配AI-Infra-Guard 安裝前掃描流程,但掃描器本身同樣不是信任豁免。
執行審計前,沙盒與 evidence promotion 必須同時滿足六項條件
- Target code 外網關閉:target-controlled build、test、process、browser、emulator、fuzzer 與 fixture processor 都不得連外;需要本機 client/server 時只開隔離 loopback。模型/orchestrator 是另一條資料路徑,審私有程式前另查 provider 的 retention、training、region 與管理政策。
- 環境清空:從空環境開始,只 allowlist 無秘密的必要變數;
HOME、暫存與 cache 都指向專屬 scratch。 - 目標唯讀:待審 Repo 與 toolchain 對受控程序唯讀,只有該 Agent 的
scratch/可寫。 - 資源上限:限制 CPU、記憶體、process、檔案大小、磁碟與 wall-clock,避免 fork bomb、壓縮炸彈或無限測試。
- 假資料與最小效果:只用 dummy principal、fixture 與假 secret;不探測 deployed endpoint、不碰其他使用者資料,也不對 live/shared process 做 availability 測試。即使研究資源耗盡,也只能在隔離 dummy process 停在證明缺陷所需的最小本機效果,不做 stress、saturation 或持續破壞。
- Evidence promotion:所有 target process 結束後,只有 trusted parent code 能提升事先 allowlist、設單檔與累計上限的 scratch-relative 檔案;用保留的 directory descriptor 逐層 no-follow traversal、nonblocking 開啟,確認 regular file、link count 為 1、identity 與前後大小未變,再 exclusive-create 目的地。Symlink、FIFO、socket、device、directory、hard link、變動中或超限檔案一律丟棄。
缺少前五項任何執行控制,就不應執行 target-controlled code;缺少第六項,則不得保留 scratch 或把它當 evidence。正確做法不是假裝測過,而是把決定性缺口留在 needs_validation。本文所在的寫作環境沒有同時具備上述完整隔離,因此只檢查公開原始碼、schema 與 validator 契約,不把三個測例寫成已跑出的 AlphaLab 成績。
還有一個宿主要補的邊界:待審 Repo 的 README、AGENTS.md、註解、錯誤訊息與 instruction-like fixture 都是不可信目標資料,不應取得改寫 auditor 權限或安全政策的指令權。這次對 pinned 文件的有界檢查沒有找到明文的 auditor-side prompt-injection 規則;如果宿主會自動載入 Repo 指令檔,應另行隔離或停用非預期繼承,只把目標文字當 evidence。
Step 1:先寫測例答案契約,再讓 Agent 看程式
不要真的在產品 Repo 隨手加三個漏洞。建立一個 throwaway 教學服務,只放假租戶、假專案與假 webhook,並由另一個人保管答案。以下三例不是 Cloudflare Repo 的漏洞,而是你要放進「被審目標」的驗收 fixture;它們刻意讓三種 verdict 各有一個合理去處。

測例 A|真正的跨租戶 IDOR:目標是 confirmed
在 fixture 中,登入者 Alice 可以呼叫 GET /api/projects/:id;handler 驗證她已登入,卻直接用全域 findById(id) 取資料,沒有把 tenant_id 或 owner 放進最後查詢。測試資料庫只放 Alice 與 Bob 兩筆虛構資料。及格證據是:fresh verifier 先重讀完整 source trace,再在隔離 loopback 送 Alice 的憑證與 Bob 的 fixture ID,最小觀察結果只到「回傳 Bob 的假專案」,立即停止,不繼續橫向枚舉。
只有入口、缺失控制、跨越邊界、受影響假資源與 bounded observed result 都成立,才能進 confirmed;severity 也只能對應實際證明的影響。若 Agent 只看到 findById 就喊高風險,卻沒有證明路由、middleware 與 tenant filter 的完整路徑,仍不及格。
測例 B|路徑穿越誘餌:目標是 rejected
fixture 的 lower-trust actor 只控制 path string;測試 root 與內容由 trusted evaluator 建立,對 target 與 actor 都唯讀且不可更換。Handler 除了 canonical boundary check,還以 descriptor-relative、no-follow traversal 開啟每個 component,確認最終目標是 root 內的普通檔案。驗證者從來源與最小 local fixture 證明 ../ 與 symlink escape 都被拒絕後,才可寫成 rejected;若只有 path.resolve 加字串 prefix check,不能預設安全。
這例專門抓「看到危險 API 就報漏洞」的錯誤。缺少第二層 hardening 不等於第一層已被繞過;如果現有控制已阻止攻擊,最多是強化建議,不能為了讓報告有內容而降成 LOW。
測例 C|Webhook 信任標頭依賴部署:目標是 needs_validation
fixture 收到 invoice.paid 後,會把指定 dummy order 標成已付款;正常路徑驗 HMAC,卻在 X-Webhook-Verified: true 時跳過,假設只有 ingress 能設定。Repo 沒有 ingress、network policy 或 backend exposure 設定,因此 source 無法回答外部 client 能否直連 app,以及 ingress 是否必定移除 client 提供的同名標頭。若任一條件不成立,未驗證的遠端 client 可能把 Bob 的 dummy order 非授權標成已付款;但 Agent 不能自行假設正式拓撲一定可繞過。
正確初始 verdict 是沒有 severity 的 needs_validation。Owner 只讀確認 route、backend exposure 與 header sanitation 設定,或在隔離 local proxy fixture 驗證 header 行為;不得向 staging、production 或其他 deployed endpoint 發送 audit traffic。若設定證據證明 app 不可直連且 ingress 一定重寫標頭,就轉 rejected;若設定顯示危險路徑存在,再把該事實與 sandboxed dummy reproduction 交給新的獨立 verifier,通過後才轉 confirmed。
Step 2:把架構圖轉成 Coverage Ledger,而不是一句「看過 auth」
正式 hunting 前,parent 先做四條 reconnaissance:產品/技術棧、principal/authority、input/sink、執行/部署。輸出不只是 architecture.md,還要把每個重要組合拆成 coverage unit:
Coverage unit = Entry surface × Trust boundary × Subsystem × Attack class
Deep profile 在真的重要時,還會再加 lifecycle
例如測例 A 不是「檢查 access control」這麼模糊,而是「GET /api/projects/:id × requireOwner × packages/api × Access control」。每一維都有給人看的 label 與從原始碼衍生的 canonical reference,再用 RFC 3986 percent encoding 組成穩定 coverage_id。wave、Agent 名稱、severity 與行號都不能塞進 ID,否則同一範圍每次執行都會變成新工作。
coverage-ledger.json 的狀態也不是任意文字:planned 不能假裝有 evidence;covered 必須有 owner、reviewed paths 與 checks;candidate 還要連到 fingerprint;blocked、deferred、out_of_scope 必須把缺口留下。parent 在 seed、每次更新與報告前都執行:
node /path/to/security-audit/validate-coverage-ledger.cjs \
/external/audit-output/coverage-ledger.json
這個「external」很重要:完整 audit 預設輸出應在目標 Repo 外,只有 parent 寫共享檔;每個 hunter/verifier 只寫自己的 scratch/。Scratch 在執行後一律視為 target-controlled,不能直接遞迴複製;只有通過上一節 descriptor-relative promotion gate 的最小 regular file 才能進 parent-owned artifacts/。除非你明確選擇且確認整個資料夾已被版本控制忽略,不要把審計產物塞回待審 Repo。想把這套概念和一般 Harness 實作對照,可接著看最小 AI Agent Harness 實作篇。
Step 3:跑完六階段,但不要把「多 Agent」誤認成獨立驗證

Phase 1|Reconnaissance:建架構、邊界與初始 Ledger
四個基線角色平行讀來源,parent 合併 architecture.md 與排序後的 ledger。若使用者設定 agent-invocation budget,Skill 會在任何 reconnaissance 以前先保留四個基線呼叫、必要 critic 與至少一個 verifier;預算連最低證據鏈都養不起時,正確狀態是 incomplete,而不是偷偷減掉驗證。
Phase 2|Coverage-led hunting:依 unit 分工,再讓 critic 找洞
Hunter 從 ledger 的 unit 出發,回報 source path、local check、候選 fingerprint 或無發現證據;coverage critic 檢查是否有表面覆蓋、錯誤 attack class、漏掉 lifecycle 或被過早關閉的 unit。Agent 數量不是 coverage,只有 ledger 裡能追到實際 reviewed paths 與 checks 的 unit 才算。
Phase 3|Candidate validation:新 verifier 先找反證
每個唯一候選交給沒有參與 hunting 的 fresh verifier。它必須重讀目前 source、尋找所有阻擋層,安全可行時才重現最小 dummy result。它能確認、降為待驗證或拒絕;不能看到 hunter 的結論後只補漂亮文字。這和AI 漏洞回報隔離與私密修補流程的核心相同:先固定證據,再決定是否值得升級處理。
Phase 4|Structured output:三種 verdict 各守自己的 schema
confirmed:完整 source trace、條件、bounded observed result、修補策略、信心與不超過實證影響的 severity。needs_validation:來源支持的候選、精確 blocker、至少一個可執行的 local 或 owner-observed plan;沒有 severity。rejected:保留原 fingerprint、trace、evidence 與反證理由,避免下次在證據未變時重複報同一個假陽性。
parent 把三類紀錄寫進 findings.json 後,同時驗證 findings 與 coverage:
node /path/to/security-audit/validate-findings.cjs \
/external/audit-output/findings.json
node /path/to/security-audit/validate-coverage-ledger.cjs \
/external/audit-output/coverage-ledger.json
Phase 5|Independent record verification:驗最終紀錄,不驗印象
Standard/deep profile 會再讓 fresh research verifier 逐筆檢查最終 confirmed 與 needs_validation;若 replacement 強化 verdict、改 root cause、trace、observed result、impact 或 severity,還要交給另一個沒參與過的 verifier。Quick profile 才會把 Phase 3 與 Phase 5 合併,但每個候選仍至少有一位獨立審查者。
Phase 6|Target-neutral reporting:從 final records、Ledger 與 hardening notes 生報告
Phase 5 後,才從 final records、coverage ledger 與保留的 hunter hardening notes 產生 REPORT.md、FINDINGS-DETAIL.md、NEEDS-VALIDATION.md。Incomplete run 可以報告已獨立驗證的紀錄,但必須列出每個未解 candidate 與 coverage gap,不得包裝成 findings;needs-validation 也不能偷加 severity。
Step 4:用 acceptance matrix 驗收,不用「找到幾個」評分
三個 fixture 跑完後,先看分類與證據是否正確,再看速度。建議把答案保留給 evaluator,對每個 run 記錄以下欄位:
- Verdict accuracy:A 是否 confirmed、B 是否 rejected、C 是否 needs_validation;任何一個被硬湊成 confirmed 都是失敗。
- Trace completeness:是否從真入口走到最後 trusted decision point,包含中間控制,而非只搜到危險函式名稱。
- Boundary discipline:是否清楚命名較低信任 principal、受影響假資源與具體結果。
- Coverage honesty:Ledger 是否保留 blocked、deferred 與 out-of-scope,不用「全部看過」掩蓋缺口。
- Verifier independence:hunter 與 verifier 是否為不同 owner;replacement 是否依 materiality 重新驗證。
- Deterministic gates:兩個 validator 是否在規定時點通過,且 prose 與 JSON 沒有 verdict 漂移。
- Cost envelope:記錄 agent invocations、模型/版本、輸入輸出 token、wall time 與費用,但不要把 token 多寡當 coverage。
特別注意:目前公開 Skill 的 budget 定義是「Agent 呼叫次數上限」,不是 provider token cap。若你要比較 token 或金額,必須由外層 Harness 從模型 API/runner telemetry 額外記錄,而且要連同 source commit、Skill commit、profile、scope、模型版本與 seed 一起保存,否則兩次數字不能公平比較。
這三個測例只能驗收 verdict discipline,不是召回率研究。它們不是同一條件的獨立重複樣本,也沒有涵蓋全部 attack classes。正式評測至少需要更多 withheld seeds、decoy、不同 subsystem、重複 run 與人工 adjudication;不要從「3/3 分類正確」推論真實世界能找到多少未知漏洞。
截至 2026 年 9 月 17 日,這次有界搜尋找到的公開植入缺陷比較,是 Cloudflare Repo 上由非維護者提出的 issue #20。其第三方報告自報 pinned Skill quick profile 三輪的中位 recall 0.467、strict precision 0.900、零 decoy 命中與 29.95 美元成本;但只有一個未公開 target、n=3、沒有 equal-cost cap,答案、raw finding 與完整 scorer 也未公開,作者又是比較產品的開發者。這只能當測試設計線索,不能獨立重算,也不能拿來替 Cloudflare 的「單次約一半」自報說法背書。
Step 5:人工反證與清理,才算完成
Validator 全綠之後,仍要由人逐筆問:入口真的可達嗎?lower-trust principal 真有該輸入權嗎?所有 middleware、資料層與部署控制都讀過嗎?local result 用的是原始、未被 Agent 修改的程式嗎?severity 有沒有超過實證 impact?修補是否放在最後可信決策點,而不是把信任移到另一層?若要把真漏洞送給維護者,再依 coordinated disclosure 流程處理,不要直接公開 PoC;也可參考Codex Security CLI 的掃描、驗證與修補閉環,但同樣保留人類最終判斷。
依組織 retention policy 保存可重現稽核需要的完整 shared-file bundle:run-metadata.json、architecture.md、coverage-ledger.json、findings.json、REPORT.md、FINDINGS-DETAIL.md 與 NEEDS-VALIDATION.md;target-controlled evidence 只保留通過安全 promotion、無秘密的最小檔案。Bundle 要限制存取並加密歸檔。環境清理則銷毀整個 disposable VM/container,確認沒有 process、對外 port 或 volume;若曾帶入真 credential,刪檔不等於撤銷,必須 rotate/revoke。
最常見的 6 個坑
坑 1:把官方內部 Harness 成績當公開 Skill benchmark
Cloudflare 長文描述的是內部、跨 Repo 系統;公開 Repo 只有起點 Skill。沒有相同 targets、模型、prompt、沙盒與 adjudication,就不能把 vendor 自報數字搬到自己的安裝。
坑 2:把三個測例都預先叫作漏洞
若答案全部是 confirmed,你只測到 Agent 會不會迎合。至少要有被現有控制反證的 decoy,以及真的缺少決定性外部事實的候選。
坑 3:把通過 JSON Schema 當成事實正確
Schema 能擋錯欄位、缺欄位與狀態矛盾,不能判斷 source trace 是不是被編造。這就是 fresh verifier 與人工複核不能刪掉的原因。
坑 4:讓 target code 看到家目錄與網路
清掉幾個 API key 不等於沙盒。必須從 empty allowlist environment 啟動,目標唯讀、scratch-only writes、外網關閉並有資源上限;做不到就不要執行。
坑 5:把多 Agent 當成 fresh eyes
如果第二個 Agent 只收到第一個人的結論、沒有重讀 source,也沒有被要求找最強阻擋層,它只是摘要員。獨立性要靠角色、輸入與 owner 邊界落實。
坑 6:以為跑一次就完成安全審計
公開 Skill 自己就強調 multiple runs 是 additive。一次沒找到,不等於沒有;prior ledger 只能幫你找 gap、重驗 changed source,不能把舊的 partial pass 變成完整覆蓋。
常見問題 FAQ
1. Cloudflare Security Audit Skill 是掃描器嗎?
不是傳統 deterministic scanner。它是協調 coding agent 的方法與產物契約,會用 Agent 讀來源、分派範圍、驗證候選,再用 validator 檢查結構;真正執行與隔離仍由你的 Agent 平台與 Harness 負責。
2. 安裝 Skill 就會自動跑完整六階段嗎?
不會。目前版本預設是 guidance mode;只有明確要求 audit/pen-test 一個 codebase、要求 full/comprehensive/end-to-end security review,或要求完整報告產物時,才進 full audit mode。一般安全問題、特定 finding triage 或 focused review 仍停在 guidance mode;語意不清時先問範圍。
3. 沒有 OS-enforced sandbox,可以只跑單元測試嗎?
不該在主機直接跑。單元測試同樣是 target-controlled code。缺少無外網、空白 allowlist 環境、唯讀目標、scratch-only writes 與資源上限時,只做 source review,並把需要執行才能決定的候選留在 needs_validation。
4. confirmed、needs_validation、rejected 哪個代表低風險?
只有 confirmed 才談 severity。Needs-validation 是缺少決定性事實,不是「低信心漏洞」;rejected 則是候選已被來源、控制或 local evidence 反證。三者不能排成高、中、低。
5. Coverage Ledger 能保證沒有漏報嗎?
不能。它讓已看、未看、卡住與延後的範圍可追蹤,降低「一句看過」造成的假完整感;attack class、scope 或 source map 本身仍可能漏,必須靠 critic、重複 run 與人工威脅建模補強。
6. 公開 Skill 的 budget 是 token 上限嗎?
不是。目前契約把 budget 定義為整個流程的 agent-invocation 上限。Token、費用與延遲要由外層 runner 另外蒐集,並綁定版本與 scope 才能比較。
7. 可以拿它掃公司正式站嗎?
不能因為裝了 Skill 就取得授權。只審你獲授權的目標,優先做 source-first 與本機假資料驗證;公開 Skill 明確禁止探測 deployed endpoint、shared infrastructure、真實身分與其他使用者資料。
8. 三個測例都分類正確,就能用在生產嗎?
不能直接推論。這只是 verdict discipline 的最小 smoke test;你還需要更多 withheld target、decoy、重複 run、不同邊界、成本量測與人類 adjudication,也要驗證自己的沙盒與 artifact promotion。
給新手的 7 個重點
- 公開 Skill 是單一 Repo 的審計起點,不是 Cloudflare 內部 fleet harness。
- 先 pin commit、讀來源、隔離安裝,再把 target-controlled build、test 與 process 切到無外網 OS sandbox;模型/orchestrator 的資料路徑另依 provider policy 審查。
- 三個測例要同時包含真缺陷、decoy 與缺部署事實的候選。
- Coverage Ledger 才是 coverage claim,Agent 數量與長報告都不是。
- Fresh verifier 的工作是反證候選,不是替 hunter 潤稿。
- Validator 證明結構一致,不證明事實成立;最後仍需人工複核。
- 做不到完整沙盒就停在 source review,絕不拿正式系統補證據。
接著閱讀
左右滑動查看更多推薦
結語:先讓系統證明它會說「不知道」
回到開頭的公式:Coverage Ledger × Fresh Verifier × Schema Gate,才把安全 Agent 的直覺變成可驗收紀錄。你的第一個成功,不是報出最多漏洞,而是對跨租戶 fixture 給出有界證據、對路徑誘餌明確拒絕、對缺部署事實的 webhook 誠實停在 needs-validation。
今天可以先做一件事:在完全可丟棄、零真實資料的環境,建立這三個答案不同的測例與 acceptance matrix,再決定是否付出完整六階段的 Agent 預算。若你想把 Skill、Harness 與自己的工作流程串起來,也可以從 AlphaLab 的完整課程開始;先練會留下證據與保留未知,才讓 Agent 接近真正的安全審計。






