事件背景:掃描沒有告警,不等於程式安全
來源事實:一篇已獲 CASCON 2026 接受、目前刊載於 arXiv 的研究,將「靜態分析沒有發現問題,但實際執行仍可被利用」定義為 Static-Pass Dynamic-Fail(SPDF)。研究團隊測試 1,355 個 Python 樣本,來源包括 SecurityEval、RedCode 與含有 LLM 生成漏洞程式碼的 CyberNative 資料集。論文原文:https://arxiv.org/abs/2609.10762
第一輪以 Bandit 與 Semgrep 組成靜態安全閘門,任何一項工具提出告警,檔案便不再進入後續流程。共有 701 個檔案被攔下,另外 654 個檔案在這組特定工具與規則下沒有任何發現。然而,後續流程仍在其中 235 個檔案找出 394 組「檔案—CWE 弱點」候選,最後於 83 個檔案取得明確的執行期利用證據;若連部分確認也計入,則是 95 個檔案。
合理推論:這項結果真正挑戰的不是靜態分析本身,而是組織常把「掃描通過」誤當成「安全驗證完成」。兩者提供的是不同層次的證據。
三層流程如何運作
來源事實:研究的第一層使用 Bandit 1.8.4.dev21 與 Semgrep 1.155.0 的 auto ruleset。Bandit 官方文件說明,它會替 Python 檔案建立抽象語法樹,再以外掛檢查節點中的常見安全問題:https://bandit.readthedocs.io/en/latest/。Semgrep 則以規則及資料流等能力比對程式模式;其官方專案也明確提醒,社群版在安全情境下受單一函式或檔案分析邊界影響,可能遺漏真陽性:https://github.com/semgrep/semgrep
第二層由 LLM 代理閱讀靜態掃描未告警的程式,提出 CWE 候選。第三層再由另一個代理查閱 MITRE CWE 與 NVD 資料、編寫攻擊測試程式,並放入停用網路、限制 256 MB 記憶體的 Docker 容器執行。每組候選進行五次評估,至少三次得到成功利用結果,才列為 CONFIRMED;只有符合弱點定義的可觀察行為才算成功,單純拋出例外並不算。
因此,這套方法的商業邏輯是「便宜的工具先廣篩,昂貴的推理與執行驗證再聚焦」。靜態階段只花約 77 秒;完整代理流程則消耗約 9,630 萬 token、歷時約 28.7 小時。這使動態驗證較適合風險導向抽查,而非不分輕重地測試每一行程式。
數字該怎麼讀
來源事實:以 654 個靜態無告警檔案為分母,只計明確確認時,SPDF 比率為 12.69%(83/654);納入部分確認則為 14.53%(95/654),約七分之一。但這不是「所有靜態掃描都漏掉七分之一漏洞」。動態測試只針對 LLM 先挑出的候選執行,未被挑中的檔案並未接受同等測試;數字描述的是整條特定管線的觀察產出,而非一般 Python 或企業生產程式碼的普遍漏洞率。
資料集差異也很大。在候選檔案—CWE 配對中,RedCode 的確認率為 33.7%,CyberNative 為 28.6%,SecurityEval 僅 5.4%。而 RedCode 貢獻了 394 組候選中的 315 組,以及 120 組明確確認中的 106 組。因此,「約七分之一」明顯受到對抗性與刻意含有弱點的樣本所拉高,不能直接套用到日常 AI 助理產生的程式碼。
真正容易漏掉的是安全語意
研究中最常確認的是 CWE-400 不受控資源消耗,共 27 例;另外包括弱隨機數、密碼雜湊成本不足與路徑穿越。CWE-338 弱密碼學隨機數有 15 個確認案例,CWE-916 密碼雜湊計算強度不足有 9 個,但兩類在初始工具輸出中都未出現。
MITRE 對 CWE-338 的定義可協助理解這個落差:非密碼學用途的亂數產生器若被拿來建立工作階段識別碼或金鑰,攻擊者可能預測結果並繞過保護;但同一個亂數函式用於模擬或抽樣時,未必構成漏洞。問題不只是程式「用了什麼 API」,還包括輸出被拿來做什麼:https://cwe.mitre.org/data/definitions/338.html
作者觀點:這正是 LLM 程式碼驗收的核心難題。型別正確、語法合法、測試案例通過,以及 SAST 沒有告警,都無法單獨回答「攻擊者能否操控輸入,讓系統越權、耗盡資源或破壞安全假設」。安全閘門應累積證據,而不是把其中任何一項工具變成免責印章。
容易忽略的研究限制
- 模型並非獨立:候選偵測與動態驗證都使用 gpt-5.4-nano。雖然提示、工具與任務不同,同一模型可能產生相關錯誤或自我確認;五次多數決只能降低隨機性,不能消除此問題。
- 沒有人工逐案覆核:所有裁決均由代理自動產生,可能同時存在偽陽性與偽陰性。
- 沙箱既保護也限制:容器沒有網路、外部服務、特權環境及特定相依套件,有些真實攻擊因此無法重現;「未觸發」不代表弱點不存在。
- 可利用不等於高衝擊:拒絕服務或弱亂數通常較容易展示,卻未必比未成功重現的程式碼注入更嚴重。單一 SPDF 比率沒有納入資產價值與衝擊權重。
- 外部效度有限:研究只涵蓋三個安全導向資料集與 Python;更換規則集、工具版本、商用掃描器或程式語言,都可能改變結果。
對台灣團隊的實際意義
作者觀點:台灣企業若已讓工程師使用 AI 產生 API、資料處理腳本、雲端自動化或內部工具,不必因此停止使用靜態掃描;更合理的作法,是重新定義「通過」的含義。靜態工具仍應在每次提交時快速攔截已知模式,但涉及身分驗證、權限、金鑰、檔案路徑、外部命令與大量資源配置的變更,應升級至隔離環境中的負向測試、模糊測試或攻擊情境驗證。
實務上,驗收政策至少要記錄程式是否由 AI 生成、觸及哪些高風險介面、靜態工具使用的版本與規則、動態測試是否真的執行,以及失敗案例是否經人工判讀。動態測試也必須放在無正式憑證、限制網路與資源、保留稽核軌跡的環境,避免「驗證漏洞」本身成為新的營運風險。
後續觀察指標
- 研究能否以不同模型分別擔任偵測者與驗證者,並加入資安專家盲審。
- 在真實企業儲存庫,而非漏洞導向資料集上,保守 SPDF 比率是否仍顯著。
- 改用更完整的跨檔案資料流規則或其他 SAST 後,哪些 CWE 類型仍持續漏網。
- 確認案例若按機密性、完整性、可用性及資產重要度加權,風險排序是否改變。
- 每個確認漏洞所需的 token、時間與人工覆核成本,能否低到足以納入日常 CI/CD。
合理推論:這篇研究最值得帶走的結論,不是某個醒目的百分比,而是一種較成熟的安全判準:靜態無告警只能表示特定工具沒有找到符合其能力與規則的問題;只有把程式放進受控環境,觀察惡意輸入下的實際行為,才開始接近「它能否抵抗攻擊」這個真正的問題。