Black Hat USA 2025 | More Flows, More Bugs: Empowering SAST with LLMs and Customized DFA
三句話摘要
騰訊安全研究員介紹如何結合 LLM 三代理流程與自訂資料流分析,解決 CodeQL 在跨執行緒、反射、傳值場景下的漏洞漏報問題。 LLM 輔助的自動化 source/sink 識別加上針對性的資料流補丁,可系統性地降低 CodeQL 的漏報率,是提升 SAST 實戰覆蓋率最具可行性的當前路徑。 CodeQL 內建規則存在大量漏報。 研究團隊嘗試用 CodeQL 偵測近期高風險漏洞時,發現主因有二:source/sink 覆蓋不完整,以及特定語言特性導致資料流中斷。這兩個根本缺陷驅動了整個研究方向。
重點整理
重點- 1
CodeQL 內建規則存在大量漏報。 研究團隊嘗試用 CodeQL 偵測近期高風險漏洞時,發現主因有二:source/sink 覆蓋不完整,以及特定語言特性導致資料流中斷。這兩個根本缺陷驅動了整個研究方向。
- 2
LLM 三代理流程可自動化 source/sink 識別。 Discover Agent 做檔案層級掃描找候選函式;Judge Agent 套用社群專家規則(如函式需為 public、回傳值需能傳播受汙染資料、回傳型別不可為 boolean)過濾誤報;Validation Agent 下載依賴該框架的真實開源專案,執行 SAST 掃描驗證函式確實被使用,未被使用的 source/sink 一律移除。
- 3
跨執行緒分析透過 Jump Step 橋接。 CodeQL 預設無法追蹤資料從 Runnable 建構子流入 `run()` 方法的路徑。研究團隊利用 `additionalValueStep` 介面,依資料是在 `start()` 前、後傳入的不同時機,分別定義跳躍策略,讓資料流路徑得以完整連通。
- 4
Java 反射分析需繞開非單調遞迴限制。 `invoke()` 方法的目標函式識別及參數傳播修補,因 CodeQL 資料流介面不允許在 `additionalValueStep` 內部呼叫資料流(否則造成循環依賴),解法是複製一份資料流實作供反射分析獨立使用,再對原始資料流打補丁,徹底切斷依賴鏈。
實用技巧與重點
乾貨- 工具:CodeQL(GitHub,核心引擎閉源,查詢庫 MIT 授權)、Fortify
- CodeQL 累計發現 418 個公開漏洞(Wall of Fame)
- LLM Agent 架構:Discover Agent → Judge Agent → Validation Agent,共三層
- 專家規則範例:函式必須 public、回傳值須傳播受汙染資料、回傳型別不得為 boolean
- 長思考(long thinking)模型在 Judge 階段表現更佳
- 掃描框架數:18 個 Go 框架
- 識別 source/sink 函式數:約 190 個
- 掃描真實專案數:5,000+ 個
- 資料流偵測提升:> 15%
- 實際案例:Apache Traffic Control 專案 `traffic_ops` SQL Injection CVE,根因為 `QueryRowx` 函式未在 CodeQL sink model 中
- 新增一個 source 函式即可額外偵測到 3 個歷史 CVE
- 跨執行緒修補策略:依資料傳入時機(建構子 / `start()` 前 / `start()` 後)分三種跳躍規則
- 反射修補策略:複製資料流實作 + 修補原始資料流的 `call-in` / `call-through` 參數傳播邏輯
- Pass-by-value 修補:定位非原始型別 field,分別對 non-post-update node 與 post-update node 的 store 操作加入 Jump Step 映射
結論
結論“LLM 輔助的自動化 source/sink 識別加上針對性的資料流補丁,可系統性地降低 CodeQL 的漏報率,是提升 SAST 實戰覆蓋率最具可行性的當前路徑。”
完整解析
詳細靜態應用安全測試(SAST)是 DevSecOps 流程的核心環節,能在不執行程式的情況下分析原始碼尋找安全漏洞。CodeQL 是目前最具代表性的 SAST 工具之一,其查詢庫以 MIT 授權開源,並已在 GitHub 上整合為 CI/CD 自動掃描服務。然而,騰訊安全研究團隊在嘗試用 CodeQL 偵測近期高風險漏洞時,發現大量漏報(false negative)。分析根因後歸納出兩類問題:第三方框架的 source/sink 函式在內建規則中覆蓋不足,以及跨執行緒、反射、傳值等語言特性導致資料流路徑中斷。
針對第一個問題,研究團隊設計了一套三層 LLM Agent 流程。Discover Agent 以原始碼檔案為單位輸入模型,配合描述目標函式特徵的 prompt(例如 SSRF 的 sink 通常是發送 HTTP 請求的函式),產出候選 source/sink 清單並過濾低信心分數結果。Judge Agent 則套用社群長期積累的專家規則,逐一審查函式名稱與函式體,移除不符條件的候選項;實驗發現長思考型模型在此階段準確度更高。Validation Agent 前往框架的開源主頁取得依賴專案清單,按 star 數排序下載後,以新增的 source/sink 規則實際執行 SAST 掃描,確認函式在真實專案中被使用才予以保留。透過這三層篩選,最終在 18 個 Go 框架中識別出約 190 個有效 source/sink 函式。
針對第二個問題,研究團隊深入 CodeQL 資料流分析(DFA)的核心機制,分別對三類中斷場景實施修補。跨執行緒方面,資料流在 Runnable 建構子呼叫處中斷,無法延伸至 `run()` 方法;解法是利用 `additionalValueStep` 的 Jump Step 介面,依資料傳入的時機點(建構子、`start()` 呼叫前或呼叫後)各自定義跳躍規則,直接從傳入點跳至 `run()` 方法的 `this` 參數節點。Java 反射方面,`invoke()` 的實際呼叫目標難以靜態確定,且 CodeQL 不允許在 `additionalValueStep` 內部呼叫資料流(否則造成非單調遞迴),解法是複製一份資料流實作供反射分析專用,再對原始資料流打補丁切斷依賴,同時修補 `call-in` 與 `call-through` 的參數傳播邏輯,使 `invoke()` 的參數與回傳值能正確傳播。Pass-by-value方面,當多份物件副本同時存在時,其中一份副本的欄位變更無法自動同步至其他副本;解法是找出非原始型別欄位的所有 store 操作,對 non-post-update node 以全域資料流定位對應參數,再對 post-update node 補上 Jump Step 映射,確保所有副本的資料流皆被追蹤。
修補完成後,研究團隊掃描逾 5,000 個開源專案,偵測到的資料流路徑提升超過 15%。以 Apache Traffic Control 的 `traffic_ops` 模組為例,該專案已啟用 CodeQL,但 SQL Injection 漏洞因 `QueryRowx` 函式未被列入 sink model 而漏報;透過掃描 `sqlx` 框架並新增該 sink,漏洞即被成功偵測。此外,單一新增 source 函式即額外觸發 3 個歷史 CVE 的偵測,反射修補也成功重現了原本無法偵測的 CVE,驗證了各項增強的實際效果。
關鍵時刻
Pipeline v2帶時間戳的重點,會在逐字稿層級分析上線後產生。目前請先透過原始影片觀看。
事實查核
Pipeline v2說法查證是下一次管線升級的一部分。KeyFrame 只會顯示它真正能驗證的內容。


