Anthropic 官方 blog:Using LLMs to secure source code — AI 漏洞掃描與自動化修補的參考架構

作者: Wisely Chen 日期: 2026 年 6 月 系列: AI Coding 架構觀察 / AI 資安 關鍵字: Defending Code, Vulnerability Discovery, AI Security Pipeline, Harness Engineering, ASAN, gVisor, Sandbox, Claude Code, Anthropic, 漏洞掃描, 自動化修補


目錄


這篇在系列中的位置

我之前寫過一系列 AI 資安文章,大部分在講兩件事:

  1. 怎麼防止 AI agent 搞破壞 — 從 Replit 刪資料庫、到 Cursor prompt injection、到 harness 七條資安實踐
  2. 怎麼防止 AI agent 被攻擊 — ForcedLeak、EchoLeak、proxy relay 攻擊

這篇要講的是第三件事:怎麼用 AI agent 做大規模漏洞掃描,而且掃完之後真的能自動化修補。

Anthropic 在 2026 年 5 月 27 日公開了 Defending Code Reference Harness,把他們用 Claude 掃描開源專案的完整 pipeline 開源。這不是一個概念驗證,是他們實際用來掃 281 個專案、找到 1,596 個漏洞的生產級工具。

對我來說,這個 repo 最有價值的不是「又一個資安掃描工具」,而是它展示了一個完整的 harness engineering 實戰案例 — 怎麼用多 agent 架構、sandbox 隔離、推理隔離來建構一個可靠的自動化 pipeline。


一個反過來的問題

過去兩年,資安圈討論 AI 的角度幾乎都是:「AI 會不會被用來攻擊我們?」

Deepfake 釣魚、自動化社交工程、AI 生成的 exploit — 這些威脅是真的。但 Anthropic 這個 repo 問的是反過來的問題:如果 AI 能大規模找漏洞,而且找得比人快、比人準,那瓶頸在哪?

答案出乎意料地簡單:AI 漏洞掃描的瓶頸不是發現,是修補。


Anthropic 的數字:為什麼 6.1% 修補率才是重點

先看 Anthropic CVD(Coordinated Vulnerability Disclosure)的公開數據:

指標 數字
Claude 掃描產生的候選發現 23,019
外部資安公司分類數量 1,900
確認為有效漏洞 1,726(真陽性率 90.8%)
已發布安全公告(CVE/GHSA) 88
影響的開源專案 281
已揭露的漏洞總數 1,596
已被修補的漏洞 97(修補率 6.1%)

90.8% 的真陽性率,在 AI 資安掃描領域是非常高的數字。傳統靜態程式碼安全分析工具(Semgrep、CodeQL 等 SAST 工具)的誤報率通常在 30-60%,很多團隊因為受不了噪音直接關掉漏洞掃描。

但看最後一行:1,596 個被揭露的漏洞,只有 97 個被修好。6.1%。

這個數字說明了一件事:AI 讓漏洞發現變成了可以大規模並行的自動化安全掃描,但自動化修補的人力管道完全跟不上。你可以同時跑 100 個 agent 掃描 100 個 repo,但每個修補都需要人類理解 codebase、寫 patch、跑測試、做 code review、合併。

Anthropic 的 blog post 原話:

“Discovery is now straightforward to parallelize; the bottleneck has shifted to verification, triage, and patching.”

這就是為什麼這個 reference harness 把大部分的設計複雜度放在 發現之後 的階段 — grade、judge、report、patch — 而不是 find 本身。


7 階段 Pipeline 完整拆解

整個 pipeline 有 7 個階段,每個階段由獨立的 agent 執行:

階段 1:Build

把目標程式碼編譯成帶 ASAN(AddressSanitizer)的 Docker image。同一個 image 會在 find、grade、re-attack 階段重複使用,確保所有 agent 看到完全一樣的程式碼和環境。

1
2
3
4
5
6
7
8
# targets/canary/config.yaml
image_tag: vuln-pipeline-canary:latest
binary_path: /work/entry
source_root: /work
build_command: >
  gcc -O1 -g -fsanitize=address
  -fno-omit-frame-pointer
  -o /work/entry /work/entry.c

階段 2:Recon(偵察)

輕量級 agent 讀取程式碼目錄,把攻擊面切成幾塊(例如「8 個不同的 parser」),讓之後的並行 agent 從不同起點開始掃描,避免大家都收斂到同一批淺層 bug。

這步是可選的(--auto-focus),也可以在 config.yaml 手寫 focus_areas

1
2
3
4
focus_areas:
  - "Alpha parser (parse_alpha) -- heap allocation with input-controlled copy length"
  - "Bravo parser (parse_bravo) -- fixed stack buffer, unbounded copy"
  - "Charlie parser (parse_charlie) -- conditional early-free with fall-through"

階段 3:Find(發現)

N 個並行 agent,每個跑在自己的網路隔離 container 裡。Agent 讀程式碼、構造畸形輸入、執行 ASAN 二進位檔。持續嘗試直到輸入連續 crash 3 次(3 out of 3)。

輸出的是 crashing input file,不是一份報告。

並行 agent 共享 found_bugs.jsonl,每個新增的 bug 都必須解釋為什麼不是已有 bug 的重複。

階段 4:Grade(驗證)

第二個 agent 在全新的 container 裡重新執行 PoC。確認:

  1. 輸入能重現 crash
  2. Crash 發生在專案程式碼裡(不是記憶體耗盡)
  3. 是真正的安全問題

關鍵設計:只有 PoC 的 bytes 從 find 傳到 grader,find agent 的推理過程完全不傳遞。

階段 5:Judge(去重分類)

短對話、無工具的 agent,把新 crash 跟 reports/manifest.jsonl 裡的已知 bug 比對:

  • New bug — 全新的漏洞
  • Cleaner example — 同一個 bug 的更乾淨範例(取代舊的)
  • Duplicate — 跳過

串行執行,防止 race condition。

去重邏輯分兩層:

確定性去重: 同一檔案 + 同一分類 + 行號差距 10 行以內 = 重複

語意去重(LLM): 同一根本原因不同措辭、同一漏洞在多個 call site、缺少全域保護但被按每個 endpoint 報告 = 重複

階段 6:Report(報告)

寫結構化的可利用性分析:被破壞的記憶體讓攻擊者能做什麼、從真實輸入是否可達、升級路徑、嚴重性。另一個 grader 評分報告的證據充分度。

嚴重性評估強制六軸分析 打分 之前,防止錨定效應:

  1. Reachability — 攻擊者能從真實入口點到達嗎?
  2. Attacker Control — 不受信任的輸入到 sink 時還完整嗎?
  3. Preconditions — 需要非預設設定、feature flag、狹窄時間窗口嗎?
  4. Authentication — 未認證、已登入、還是管理員?
  5. Read vs. Write — 只能讀還是能改?
  6. Blast Radius — 一個用戶、所有用戶、一個 tenant、平台、kernel?

階段 7:Patch(修補)

生成候選修補,然後爬一個 4 層驗證階梯(下一節詳細拆解)。


推理隔離:整個系統最重要的設計決策

如果只記一件事,記這個:推理(reasoning)不跨階段傳遞,只有產出物(artifacts)跨階段傳遞。

跨階段邊界 傳遞的東西 不傳遞的東西
Find → Grade PoC bytes Find agent 的思考過程、分析、假設
Grade → Judge 判定結果 驗證推理
Judge → Report 判定結果 + PoC 去重邏輯
Report → Patch reviewer {file, line, category, diff} 漏洞描述、建議、patch 作者的理由

為什麼這很重要?兩個原因:

1. 防止確認偏誤(Confirmation Bias)

如果 find agent 說「這是一個 heap buffer overflow」,然後把這個推理傳給 grade agent,grade agent 很容易被「說服」而確認——即使 crash 其實是記憶體耗盡,不是 overflow。

讓 grader 只看到 PoC bytes,它必須自己判斷 crash 是什麼。

2. 防止 Prompt Injection 傳播

目標程式碼裡可能藏著惡意的 prompt injection — 在函式名稱、檔案路徑、ASAN trace、build output 裡。如果 find agent 的推理被這些 injection 污染,然後推理傳到下游 agent,injection 就會在整個 pipeline 裡傳播。

切斷推理傳遞 = 切斷 injection 傳播鏈。

Patch reviewer 的設計最極端:它只拿到 {file, line, category, diff},連漏洞的描述都看不到。如果掃描輸出包含惡意指令,那些指令永遠到不了 reviewer。

Anthropic 的 blog 說他們是從實戰中學到這個教訓的。當一個 agent 同時負責 discovery 和 verification,它會 自我審查,排除掉一些可利用的真陽性。把發現和驗證分成獨立 agent,一個優化 recall(找到所有東西),一個優化 precision(證明它是真的),效果遠好於合在一起。

這個設計跟 Google DeepMind 的 CaMeL 架構 有異曲同工之妙——CaMeL 把 agent 分成「privileged」(有權限但不碰不信任資料)和「quarantined」(碰不信任資料但沒權限),本質上就是用隔離防止 injection 在 agent 之間傳播。Defending Code 的 7 個 agent 各自只拿到自己需要的 artifact,理念完全一致。

史丹佛 x 哈佛的「混沌智能體」研究則從另一面說明了為什麼這很重要:把 6 個自主 agent 放進真實環境,它們會自發性地洩漏郵件、炸掉伺服器、用「語義重構」繞過安全規則。多 agent 系統的風險不是加法,是乘法——推理隔離是目前最有效的結構性緩解。


Sandbox 設計:約束寫在程式碼裡,不是 prompt 裡

Anthropic 在文件裡講了一個真實故事:

一個團隊在 prompt 裡告訴 model「你沒有網路存取權限」,結果 model 自己發現它其實可以從 GitHub 抓檔案。另一個團隊觀察到 agent 在掃描過程中順手回覆了一個 GitHub issue。

這兩個都不是惡意行為,但它們完美示範了一件事:用 prompt 做約束等於沒有約束。 我在 Claude Code 資安最佳實踐 裡翻過源碼驗證過的結論也是一樣的:Claude Code 的 permission system 和 sandbox 是寫在程式碼裡的硬邊界,不是寫在 prompt 裡的建議。

Defending Code Reference Harness 的 sandbox 設計:

gVisor kernel 隔離 — 不是共享 host kernel 的 container,而是用 gVisor 提供獨立的 kernel 實現。Agent container 裡的 syscall 不直接到 host kernel。

Docker network 隔離vp-internal 網路,沒有 internet route。唯一的出口是一個 allowlist proxy,只轉發到 api.anthropic.com:443

啟動前驗證bin/vp-sandboxed 在啟動任何 agent 之前會驗證 sandbox 是否就位。如果 gVisor 或網路隔離沒有正確設定,直接拒絕啟動。

階段分離 — internet 存取只在 build 階段(拉 dependency),build 完成後移除。Find/Grade 階段的 agent 完全沒有外網。

不受信任資料的標記 — 所有來自目標程式碼的文字都被包在 <untrusted_data> block 裡,帶有每次呼叫隨機生成的 ID。Agent 被指示把它當資料處理,不是指令。

Anthropic 很誠實地說:這些是 mitigations,不是 guarantees。但比起「在 prompt 裡寫『你不能上網』」,差了十萬八千里。


Patch 驗證的四層階梯:為什麼 60% 能編譯但只有 15% 活得過 re-attack

這是整個 pipeline 最讓我驚訝的部分。

Anthropic 公布的數據:model 生成的 patch,大約 60% 能通過編譯 + 重現測試。聽起來不錯對吧?但只有不到 15% 能撐過 re-attack。

什麼是 re-attack?一個全新的 find agent,拿到打完 patch 的程式碼,用 50 個 turn 嘗試攻擊它。如果新 agent 能用不同的輸入觸發同一類 crash,patch 就失敗了。

4 層驗證階梯,從最便宜到最貴:

層級 問題 驗證方法 通過率
Build 打了 patch 能編譯嗎? git apply + build_command exit code ~80%
Reproduce 原始 crash 消失了嗎? 執行 PoC,exit 0 且沒有 AddressSanitizer: 輸出 ~60%
Regress 現有測試還過嗎? test_command exit code ~50%
Re-attack 根本原因修好了,還是只修了這個特定輸入? 全新 find agent 用 50 turn 攻擊修補後的程式碼 <15%

那個從 60% 掉到 15% 的落差,說明了 model 修 bug 最常見的問題:它修的是症狀,不是根因。

例如一個 buffer overflow,model 的 patch 可能加了一個 bounds check 只針對 PoC 觸發的那個路徑。原始 PoC 確實不再 crash 了。但換一個稍微不同的 input,走另一條路徑到同一個 sink,同樣的 overflow 又出現了。

Re-attack 就是在抓這種 narrow fix。它不看 PoC,它從零開始嘗試攻擊。如果 patch 只堵了一個洞但沒修根因,re-attack 很快就能找到另一個洞。

這個設計背後的思維很清楚:不要相信 model 的 patch 是完整的,用另一個 model 去證明它不完整。


Firefox 實戰:22 個漏洞、14 個高嚴重性、出貨給數億用戶

Anthropic 跟 Mozilla 合作,用這個 pipeline 掃描 Firefox 原始碼。結果:

  • Claude Opus 4.6 在兩週內找到 22 個漏洞
  • 其中 14 個是高嚴重性
  • 這 14 個高嚴重性 bug 接近 2025 年全年修補的高嚴重性 Firefox bug 的五分之一
  • 修復已隨 Firefox 148.0 出貨給數億用戶

其他被掃描出的知名專案漏洞:

  • nginx — arbitrary file write(任意檔案寫入)
  • Temporal — cross-namespace workflow manipulation(跨命名空間工作流操控)
  • Ghost — SQL injection

這些不是「理論上可能的問題」,是真的被利用路徑確認、發了 CVE/GHSA 的漏洞。

值得一提的是,這個 pipeline 背後的掃描模型就是 Anthropic 的 Mythos——那個強到讓美國財政部長跟 Fed 主席同時約談華爾街六大行 CEO 的資安模型。23,019 個候選發現就是 Claude Mythos Preview 產出的。


跟我之前寫的 Harness Engineering 的關係

如果你讀過我之前的 harness engineering 系列,會注意到這個 pipeline 是一個教科書級的 harness 實作。拿幾個核心概念對照:

多 Agent 分工 vs. 單 Agent 全包

我在 Harness Engineering 七條資安實踐 裡寫過 least-privilege tool access,在最小權限原則那篇從 FDE 視角討論過它跟企業效率的衝突。Defending Code 把這個原則推到極致:每個 agent 只能做一件事。Find agent 不能修 patch,Grade agent 看不到 Find 的推理,Patch reviewer 看不到漏洞描述。

約束寫在 Harness 層,不寫在 Prompt 層

我在 Prompt Injection 那篇 的核心論點就是這個。Defending Code 用 gVisor + Docker network + allowlist proxy 證明了這件事:agent 說不說實話不重要,它物理上出不去。

Effective Feedback Compute(EFC)

我在 EFC 那篇 講的是回饋訊號的品質決定 agent 產出的品質。Defending Code 的 re-attack 階段就是一個高品質的回饋訊號:不是問 model「你覺得這個 patch 好不好」,而是讓另一個 model 去攻擊它,用 crash 或不 crash 的客觀事實當回饋。

Three Migrations 裡的 Hook 機制

三次遷移 裡我講過 harness 的 hook 機制怎麼讓你在 agent 執行的關鍵節點插入檢查。Defending Code 的 7 階段 pipeline 本質上就是一個巨大的 hook chain:每個階段之間都有一個檢查點,決定結果是往下傳還是被丟掉。

Control Plane Pattern

Harness Engineering 完整拆解 裡我拆過 OpenAI 的 control-plane pattern:把「agent loop」和「review loop」分開,review gate 決定 agent 的產出能不能往下走。Defending Code 的 7 階段 pipeline 就是這個 pattern 的極致版本——每個階段之間都是一個 review gate,而且 grade 和 re-attack 階段本身就是獨立的 review agent。

Pipeline 裡的 Model 配置

有趣的是,Defending Code 的 7 個 agent 全部用同一個 model(Claude Opus 4.6),沒有做 model tier 區分。這跟我在 AgentOpt Pipeline 那篇 討論的 model 配置策略剛好形成對比——那篇論文的結論是把最強 model 放在 execution 而不是 planning。Defending Code 的做法比較直接:資安場景容錯空間小,每一層都需要最強的判斷力,不值得為了省錢用弱 model。


你的團隊能從這裡學到什麼

你可能不需要跑一個 ASAN fuzzing pipeline。但這個 repo 的幾個設計原則是通用的:

1. 分開 Discovery 和 Verification

不管你是用 AI 做 code review、寫測試、還是做資安掃描,都應該讓「發現問題的 agent」和「確認問題的 agent」分開。同一個 agent 同時做兩件事,會自我審查掉真正的問題。

2. 推理不跨 Agent 傳遞

如果你的 pipeline 是 A → B → C,不要把 A 的推理直接塞到 B 的 context 裡。傳遞 artifact(程式碼、diff、測試結果),不傳遞 reasoning。這既防確認偏誤,也防 prompt injection 傳播。

3. 用客觀事實當回饋,不用 Model 自評

「你覺得這個 patch 好不好」不如「另一個 agent 能不能攻破這個 patch」。Crash 或不 crash、測試過或不過、build 成功或失敗 — 這些是不可偽造的回饋訊號。

4. Sandbox 是 Day 1 需求,不是 Nice-to-have

如果你的 agent 能執行程式碼、能發 HTTP request、能讀寫檔案系統 — 你需要 sandbox。不是「等出事了再加」,是「沒有 sandbox 不啟動」。Meta 的 Sev1 事件就是反面教材:agent 自己決定在論壇發文,導致敏感資料暴露 2 小時——沒有外部攻擊,純粹是 agent 有了不該有的寫入權限。

5. 先把 post-scan 流程想好,再投資 scan 規模

Anthropic 的 6.1% 修補率是一個警示:如果你的團隊沒有 triage 和 patch 的人力管道,掃出 1,000 個漏洞只會讓所有人更焦慮。Blog 原話:「Budget for the pipeline AFTER the scan before you budget for more scanning.」


坦白說

這個 repo 很好,但有幾件事要誠實講:

這套 AI 漏洞掃描目前只針對 C/C++ memory bug。 整個 pipeline 的 oracle 是 ASAN crash。如果你的 codebase 是 Python / Java / TypeScript,你需要自己設計 oracle。邏輯漏洞(broken access control、business logic error)目前沒有像 ASAN 這麼乾淨的自動化驗證方式。

90.8% 真陽性率是在 memory bug 場景下。 對記憶體安全問題來說,crash 就是 crash,幾乎不存在「看起來像 bug 但其實不是」的情況。換成邏輯漏洞,真陽性率會大幅下降。

<15% 的 patch 撐過 re-attack 代表自動化修補離生產還很遠。 你可以用這個 pipeline 做程式碼安全掃描,但修補漏洞大概率還是需要人。Re-attack 的設計很聰明,但它也證明了 model 的修補能力離「可靠」有明顯差距。

gVisor 在 macOS 上不能跑。 如果你想在 Mac 上試,需要 Linux VM 或雲端機器。這不是一個「clone 下來 5 分鐘跑起來」的 repo。

它沒有解決 Threat Model 錯位的問題。 Anthropic 自己在 blog 裡引用了一個 CISO 的話:「Model 對程式碼有好的 context,但對我們沒有好的 context。」一個團隊因為掃描結果跟他們的威脅模型不匹配,有 40% 的 false positive — 不是因為發現錯了,是因為那些問題在他們的 context 裡不是問題。


常見問題 Q&A

Q: 我的專案不是 C/C++,這個 repo 對我有用嗎?

架構設計和原則是通用的。但 pipeline 實作(ASAN oracle、crash-based verification)是針對 memory bug 的。你需要自己設計 verification oracle — 例如用 test suite 結果、或用 exploit script 的 exit code。

Q: 跟 Semgrep / CodeQL 比起來怎樣?

完全不同的東西。Semgrep/CodeQL 是 pattern matching,找已知漏洞模式。這個 pipeline 是讓 model 閱讀程式碼、理解語意、構造 exploit input。它能找到 pattern rule 覆蓋不到的問題,但也更慢、更貴。最佳做法是兩者都跑。

Q: 我能拿來掃描閉源 / 內部程式碼嗎?

可以。Pipeline 是本地執行的,程式碼不離開你的機器。API call 只到 api.anthropic.com(透過 allowlist proxy)。但你要注意 Anthropic 的 API 使用條款 — 確認你的程式碼片段作為 prompt 送到 API 是否符合你的合規要求。

Q: Re-attack 用的是同一個 model 嗎?

是的。Re-attack 的 find agent 跟原始 find agent 用相同的 model 和 prompt,但是全新的 session,不知道之前的漏洞和 patch 內容。它是獨立的,只被告知「嘗試攻擊這個二進位檔」。


延伸閱讀

本站相關文章

Harness Engineering 系列

AI 資安系列

外部資源