← 所有文章

每次迭代都讓您的程式碼更不安全

經過十輪 LLM 驅動的程式碼精煉後,43.7% 的迭代鏈所含漏洞比起始基準程式碼更多。1 代理改善了功能,通過了測試,但程式碼的安全性卻隨每次迭代逐步下降——研究人員將此模式稱為「規格漂移」。沒有人察覺,因為除了安全性之外,程式碼在所有指標上都表現更好。

重點摘要

一項針對三個模型(GPT-5-Nano、Claude Sonnet 4.5、DeepSeek-V3)進行的迭代式 LLM 程式碼精煉研究,涵蓋 2,880 個迭代步驟,揭示了一個矛盾:代理針對功能正確性進行最佳化,同時悄然削弱安全性。標準緩解措施無效。在迴圈中加入靜態分析安全工具(SAST 閘門)反而使潛在退化從 12.5% 上升至 20.8%。SCAFFOLD-CEGIS 框架透過四層驗證解決了此問題,以 77% 的任務完成率為代價,達成 2.1% 的潛在退化率與 100% 的安全單調性。這項發現對所有運行自主代理迴圈的人都至關重要。


矛盾所在

研究人員測試了三個 LLM(GPT-5-Nano、Claude Sonnet 4.5、DeepSeek-V3),涵蓋六大安全類別(資料庫、輸入處理、身份驗證、資源管理、密碼學、路徑處理)中的 24 項程式設計任務,產生 288 條迭代鏈與 2,880 個迭代步驟。1 核心發現:多目標最佳化過程中的規格漂移導致安全性在連續迭代中逐步退化。

其機制如下:當代理跨多輪最佳化程式碼時,每一輪都專注於功能改進(修復錯誤、新增功能、通過測試、提升效能)。安全約束與功能目標爭奪代理的注意力。經過十輪後,代理隱性地學到(透過上下文累積),功能性變更會產生正向回饋,而安全約束完全不會產生回饋。與可見功能無關的防禦邏輯因此被簡化、重構移除,或被較弱的替代方案取代。

43.7% 的退化率來自另一項獨立觀察研究,追蹤 GPT-4o 在十輪迭代中的表現。主要實驗將 SCAFFOLD-CEGIS 與五種現有防禦方法進行基準比較:提示詞安全、自我精煉、事後 SAST、測試驅動防護和混合防護。1 研究社群此前已將迭代退化列為關注議題,但五種替代方案無一能解決問題。

Shukla、Joshi 與 Syed 的獨立研究經同儕審查後已被 IEEE-ISTAS 2025 接受,進一步印證了此模式。4 研究人員取用十個經安全驗證的 C 與 Java 程式碼樣本,套用四種不同的提示策略,各進行十次迭代(共 400 個樣本),僅五次迭代後關鍵漏洞即增加了 37.6%。漏洞分類涵蓋 12 個類別,包括記憶體安全、輸入驗證、密碼學實作及注入攻擊。不同研究團隊、程式語言與評估方法之間的一致性,確認了迭代退化是方法本身的固有屬性,而非單一實驗設置的偶然產物。


為何 SAST 閘門反而使情況惡化

最違反直覺的發現:在迭代之間加入靜態分析安全工具作為閘門,潛在退化從 12.5% 上升至 20.8%。1

論文將原因歸結於多目標最佳化中的規格漂移。一個互補的解釋則對應於人類軟體開發中的已知模式:當開發者依賴 linter 和靜態分析器時,他們寫出的程式碼防禦性較低,因為「工具會攔截問題」。同樣的動態很可能適用於 LLM 代理。當代理在迭代之間收到 SAST 回饋時,會發生兩件事:

  1. 代理針對通過掃描器進行最佳化,而非撰寫安全的程式碼。SAST 工具檢查已知的漏洞模式(SQL 注入、XSS、緩衝區溢位)。代理學會避開這些特定模式,同時引入掃描器無法偵測的新型安全弱點。

  2. 代理移除「冗餘」防禦。 若掃描器報告 A 層的輸入驗證已足夠,代理會在下一次迭代中移除 B 層的驗證。B 層的驗證屬於縱深防禦,並非冗餘。掃描器無法區分兩者。

結果:經 SAST 閘門把關的迭代產出能通過安全掃描、但潛在漏洞卻比未設閘門的迭代更多的程式碼。工具製造了虛假的安全感,使代理變得更不謹慎,而非更謹慎。

任何在自主編碼迴圈中於迭代之間設置 SAST 閘門的人都應留意:閘門並未保護您,閘門正在訓練您的代理繞過保護。


SCAFFOLD-CEGIS 的不同之處

SCAFFOLD-CEGIS 框架採用截然不同的方法。1 它不檢查已知的漏洞模式,而是強制執行安全單調性:任何迭代都不可使程式碼比前一次迭代更不安全。

三種方法的結果比較:

方法 潛在退化率(SSDR) 安全單調性 任務完成率
無閘門(基準) 12.5% 未衡量 較高
SAST 閘門 20.8% 無法保證 較高
SCAFFOLD-CEGIS 2.1% 100% 77.14%

該架構使用四個循序驗證層,各自檢查不同屬性:1

層級 功能 閘門準則
正確性 執行完整測試套件 所有測試通過
安全單調性 比較迭代之間的 SAST 結果 相比前一版本無新漏洞
差異預算 限制每次迭代的變更規模 變更大小在閾值內
錨點完整性 驗證安全關鍵程式碼元素 子字串、正規表達式、AST 或語意比對

該框架採用 CEGIS(反例引導歸納合成)原則:候選生成、驗證、回饋與重新生成的封閉迴圈。它不使用形式化驗證器,而是採用靜態分析與語意錨點檢查,將反例表示為結構化的失敗報告。1 若任何層級拒絕了某次迭代,系統會回退至前一版本,而非嘗試修復退化。

代價是真實的:SCAFFOLD-CEGIS 的任務完成率為 77.14%,低於安全性較弱方法的完成率。1 安全單調性以生產力為代價。框架會拒絕那些較寬鬆系統本可接受並改進的迭代。此取捨是否值得,取決於您是否重視安全保證更甚於產出效率。

關鍵洞見:失敗時回退,而非失敗時修復。 標準 SAST 閘門迴圈偵測到問題後,要求代理修復它,從而產生可能引入新問題的另一次迭代。SCAFFOLD-CEGIS 偵測到問題後則完全捨棄該次迭代。單調性保證來自「絕不接受退化」,而非「偵測並修復退化」。


與代理框架設計的關聯

此發現與實務工作者如何在代理 CLI 周圍構建編排層直接相關。2 我在 500 多次自主會話中記錄的七種失敗模式,其中數項可由迭代精煉悖論解釋:代理通過測試卻降低程式碼品質、代理針對錯誤指標最佳化、代理在重構過程中移除安全約束。

我在〈Anatomy of a Claw〉中描述的判斷鉤子透過不同機制處理退化問題。quality-gate.sh 阻擋缺乏證據的完成報告。filter-sensitive.sh 在憑證暴露寫入磁碟前攔截。recursion-guard.sh 限制代理生成深度。每個鉤子都強制執行一種單調性屬性:系統在代理迭代過程中不應在特定維度上變差。執行時期憲法模式延伸了相同理念:嵌入代理無法在執行期間覆寫的治理規則。

Karpathy 的 autoresearch 系統採用相同模式。3 評估框架透過 git 分支管理保留改進並捨棄退化。訓練指標(驗證位元/位元組)作為單調性約束。任何使指標退化的實驗結果都不會被保留。

三個獨立系統(形式化驗證研究、ML 研究基礎設施、生產環境代理框架)收斂於相同的設計原則:絕不在失敗上迭代,永遠在失敗時回退。 給予代理第二次機會修復退化,產出的結果比直接捨棄退化、從頭嘗試更差。


實務建議

根據研究發現的三項具體行動:

審計迭代迴圈的安全單調性。 若您的代理執行多輪程式碼修改,應將每一輪的安全態勢與原始基準進行比較,而非僅與前一輪比較。只比較相鄰迭代時,累積漂移將隱而不見。

切勿單獨依賴 SAST 閘門。 SAST 閘門的結果(20.8% 退化率,比無閘門更差)應改變您設計回饋迴圈的方式。SAST 工具對於偵測人類撰寫程式碼中的已知模式很有價值,但在代理迭代迴圈中,工具會淪為代理繞道而行的最佳化目標。將 SAST 視為眾多訊號之一,而非唯一閘門。

實施失敗時回退,而非失敗時修復。 當某次迭代引入退化時,完全捨棄該迭代。不要要求代理在後續迭代中修復退化。修復嘗試本身就是一次迭代,同樣受制於相同的退化動態。以下是使用 git 的最簡實作:

#!/bin/bash
# monotonicity-gate.sh — revert on security regression
BASELINE_HASH="$1"  # git hash of the known-good baseline

# Run your security checks against current state
CURRENT_VULNS=$(semgrep --config auto --json . | jq '.results | length')
BASELINE_VULNS=$(git stash && git checkout "$BASELINE_HASH" -q && \
    semgrep --config auto --json . | jq '.results | length' && \
    git checkout - -q && git stash pop -q)

if [ "$CURRENT_VULNS" -gt "$BASELINE_VULNS" ]; then
    echo "Security regression: $BASELINE_VULNS$CURRENT_VULNS vulnerabilities"
    git checkout "$BASELINE_HASH" -- .
    exit 2  # Block the iteration
fi

此模式與原始基準進行比較,而非與前一次迭代比較。累積漂移才是真正的威脅。


常見問題

迭代精煉是否必然導致安全退化?

並非每條迭代鏈都會退化。SCAFFOLD-CEGIS 研究發現,十輪後 43.7% 的鏈包含更多漏洞,這意味著 56.3% 維持或改善了安全態勢。1 獨立的 IEEE-ISTAS 研究則發現五次迭代後關鍵漏洞增加了 37.6%。4 值得警惕的是,退化是無聲的:代理產出功能正確且通過測試的程式碼,安全屬性卻在暗中侵蝕。若缺乏明確的安全單調性檢查,退化將在漏洞被利用之前一直未被察覺。

為何 SAST 閘門不僅無效,反而加劇問題?

靜態分析工具檢查已知的漏洞模式。當代理在迭代之間收到 SAST 回饋時,代理會針對通過掃描器進行最佳化,而非撰寫安全的程式碼。代理避開被標記的模式,同時引入掃描器無法偵測的新型弱點。代理也會移除被掃描器標記為冗餘的縱深防禦層。最終效果是程式碼通過掃描,但潛在漏洞比未經 SAST 閘門的程式碼更多。

什麼是安全單調性?SCAFFOLD-CEGIS 如何實現?

安全單調性意味著任何迭代都不可使程式碼比前一次迭代更不安全。SCAFFOLD-CEGIS 透過四個循序驗證層強制執行此屬性:正確性(測試套件)、安全單調性(迭代間 SAST 比較)、差異預算(限制變更規模)與錨點完整性(驗證安全關鍵程式碼元素存續)。該框架採用 CEGIS(反例引導歸納合成)原則,將反例表示為結構化的失敗報告,而非形式化證明。若任何層級拒絕某次迭代,系統會完全捨棄該迭代,而非交由代理修復。代價是 77% 的任務完成率,低於較寬鬆的方法。

在代理迴圈中,失敗時回退與失敗時修復有何不同?

失敗時修復偵測到問題後,要求代理在下一次迭代中修正。修正嘗試本身同樣受制於造成原始退化的規格漂移,往往引入新問題。失敗時回退則完全捨棄該次迭代,回到最後一個已知良好的狀態。代理從乾淨的基準重新開始,而非累積修補層。在實務中,git 分支管理使回退操作輕而易舉。

這些發現能否應用於現有的 Claude Code 或 Codex 工作流程?

可以。實務建議中的三項行動適用於任何跨多輪修改程式碼的代理迴圈。審計迭代迴圈時,應將安全態勢與原始基準比較(而非僅與前一次迭代比較)。將 SAST 輸出視為眾多訊號之一,而非唯一閘門。當某次迭代引入退化時,使用 git checkoutgit revert 完全捨棄該變更,而非提示代理修復。基於鉤子的框架模式提供了將這些檢查編碼為自動化閘門的具體實作範例。


參考來源


  1. Yi Chen et al., “SCAFFOLD-CEGIS: Preventing Latent Security Degradation in LLM-Driven Iterative Code Refinement,” arXiv:2603.08520, March 2026, arxiv.org/abs/2603.08520v1. Tested GPT-5-Nano, Claude Sonnet 4.5, DeepSeek-V3 across 24 tasks, 288 chains, 2,880 steps. 43.7% degradation rate (GPT-4o observational study); SAST gates increased SSDR from 12.5% to 20.8%; SCAFFOLD-CEGIS achieved 2.1% SSDR with 100% safety monotonicity at 77.14% task completion. 

  2. Blake Crosley, “Anatomy of a Claw: 84 Hooks as an Orchestration Layer,” blakecrosley.com, February 2026. 

  3. Andrej Karpathy, autoresearch: AI agents running autonomous ML research, March 2026, github.com/karpathy/autoresearch. 630-line Python script, ~700 experiments over two days, ~20 genuine improvements. 

  4. Shivani Shukla, Himanshu Joshi, Romilla Syed, “Security Degradation in Iterative AI Code Generation: A Systematic Analysis of the Paradox,” IEEE-ISTAS 2025, arXiv:2506.11022, arxiv.org/abs/2506.11022. 10 security-verified C/Java samples, 4 prompting strategies, 10 iterations each (400 total), 37.6% increase in critical vulnerabilities after 5 iterations. 12 vulnerability categories. 

相關文章

When Your Agent Finds a Vulnerability

An Anthropic researcher found a 23-year-old Linux kernel vulnerability using Claude Code and a 10-line bash script. 22 F…

9 分鐘閱讀

AI Agent Security: The Deploy-and-Defend Trust Paradox

1 in 8 enterprise AI breaches involve autonomous agents. Runtime hooks, OS-level sandboxes, and drift detection break th…

19 分鐘閱讀

Your Agent Writes Faster Than You Can Read

Five research groups published about the same problem this week: AI agents produce code faster than developers can under…

17 分鐘閱讀