Black Hat Europe 2025 | Flaw And Order: Finding The Needle In The Haystack Of CodeQL Using LLMs
三句話摘要
CyberArk 研究員示範如何將 CodeQL 靜態分析與 LLM 結合,用不到 80 美元在兩天內找出多個知名開源專案的真實 CVE。 靜態分析(CodeQL)解決「看哪裡、找什麼」,CSV 預萃取解決上下文速度,引導式提問解決 LLM 焦點漂移——三層組合讓 80 美元的成本找出互聯網頂級開源專案的真實 CVE。 LLM 找漏洞有兩個根本問題:位置(where)與類型(what):直接餵程式碼給 LLM 會因選擇空間過大而產生幻覺,Google Big Sleep 和 OpenAI Hard Vark 等方案都是先鎖定位置與類型才讓 LLM 介入,本研究用 CodeQL 靜態分析解決這兩個問題。
重點整理
重點- 1
LLM 找漏洞有兩個根本問題:位置(where)與類型(what):直接餵程式碼給 LLM 會因選擇空間過大而產生幻覺,Google Big Sleep 和 OpenAI Hard Vark 等方案都是先鎖定位置與類型才讓 LLM 介入,本研究用 CodeQL 靜態分析解決這兩個問題。
- 2
策略倒轉:從「找真陽性」改為「剔除假陽性」:傳統方法期待 LLM 從無到有找出漏洞;本方法讓 CodeQL 先產生所有潛在問題,再讓 LLM 判斷哪些是假陽性,剩下的就是真實漏洞,邏輯更可靠。
- 3
上下文挑戰靠 CodeQL 資料庫轉 CSV 解決:無法用正則表達式從行號提取完整 C 函式,也無法用即時 CodeQL 查詢(每次 2.5 分鐘),改為一次性預萃取所有需要的資訊到 CSV,後續每次搜尋不到 3 秒。
- 4
引導式提問讓 LLM 聚焦正確維度:LLM 看到完整上下文後仍容易只盯著 CodeQL 標記的那一行,引導式提問強迫它先用文字描述資料流(來源、目標大小、宣告位置、是否變化),迫使正確資訊進入預測序列,再給出最終判斷,無需微調 CodeQL 查詢即可大幅降低假陽性。
實用技巧與重點
乾貨- 花費:不到 80 美元、不到兩天
- CodeQL 掃描結果量:curl 929 筆、Redis 6,409 筆、Linux kernel 36,000+ 筆、FFmpeg 46,000+ 筆,合計超過 90,000 個潛在問題
- 若每問題 3 分鐘人工審查,需要超過 4,000 小時、兩年以上
- 靜態分析工具誤報率實測:某組織回報 80% 為假陽性,最終棄用工具回歸人工審查
- 工具:CodeQL(GitHub 擁有,免費,支援 CI/CD / 命令列 / VS Code 擴充)
- CodeQL 資料庫可直接從 GitHub API 免費下載,無需自行編譯
- 預萃取所有 CSV 耗時:無論倉庫大小約 15 分鐘
- CSV 查詢速度:不到 3 秒
- FFmpeg 按需 CodeQL 查詢估算時間:46,000 × 2.5 分鐘 = 超過 93,000 分鐘
- 實驗規模:100 個 GitHub 星標最多的 C 語言倉庫
- 整體結果:874 個問題 → 過濾後 239 個(減少 73%)
- 具體問題類型與 CVE:
- `scanf 缺少回傳值檢查`:549 → 162 → 101 個真陽性 → 1 個 Red Hat CVE
- `scanf 回傳值檢查不正確`:42 → 19 → 1 個真陽性 → FFmpeg CVE
- `copy 函式使用 source 大小`:189 → 16(減少 91%)→ Redis CVE、LibreOffice CVE
- `scanf 未指定長度`:84 → 42 → 35 個真陽性 → Linux CVE、PyBullet CVE、Red Hat CVE
- 引導式提問產生的假陽性中真陽性比例:約 3%–5%
- LLM 使用:ChatGPT(低 temperature 參數以確保精確資料流描述)
- 工具名稱:Valhalla(開源,支援 C/C++)
- 語言支援現況:目前僅支援 C 與 C++,需社群貢獻更多 CodeQL 查詢與引導式問題
結論
結論“靜態分析(CodeQL)解決「看哪裡、找什麼」,CSV 預萃取解決上下文速度,引導式提問解決 LLM 焦點漂移——三層組合讓 80 美元的成本找出互聯網頂級開源專案的真實 CVE。”
完整解析
詳細安全研究員 Simha Katzman 在 Black Hat 上以一個挑釁性的問題開場:那滿滿一屏的 CVE 列表,他只用了兩天和不到 80 美元就找齊了。然而,這場演講的核心不是在炫耀 LLM 有多神,而是先揭穿一個普遍的迷思——直接把程式碼丟給 ChatGPT 叫它找漏洞,結果幾乎都是幻覺出來的假問題,curl 團隊和 HackerOne 已明確禁止以此方式提交 issue。LLM 的本質是預測下一個詞,當「漏洞在哪」和「什麼類型的漏洞」兩個問題同時懸而未決,模型就會在海量可能性中迷失,產生大量 AI CVE 垃圾。
Katzman 的核心洞察是:不要讓 LLM 從零找漏洞,而是讓靜態分析工具 CodeQL 先鎖定嫌疑位置與問題類型,再讓 LLM 負責判斷哪些是假陽性。這個邏輯反轉至關重要——CodeQL 的輸出永遠指向具體位置,LLM 不再需要猜測「在哪裡看」,只需回答「這是真的問題嗎」。然而 CodeQL 本身的問題是誤報率極高:掃描四個主流開源專案就累積超過 9 萬筆結果,若每筆 3 分鐘人工審查需要超過兩年,實務上根本無法消化。
實作過程中他遇到兩個技術壁壘。第一個是「上下文挑戰」:CodeQL 只輸出行號,而從行號提取完整 C 函式無法靠正則表達式達成(C++ 不是規則語言,巨集、字串中的括號、函式指標都會讓解析失敗),而即時執行 CodeQL 查詢每次要 2.5 分鐘,光是 FFmpeg 就會累積超過 9.3 萬分鐘。解決方案是一次性預萃取:用 CodeQL 查詢把函式定義、全域變數、結構型別等全部倒進 CSV 檔案,耗時約 15 分鐘,之後 LLM 每次按需查找只要不到 3 秒。第二個是「焦點挑戰」:即便 LLM 拿到完整上下文,它仍傾向死盯著 CodeQL 標記的那一行紅色警告,而忽略旁邊對判斷至關重要的資訊(例如:source buffer 和 destination buffer 是否使用同一個巨集分配相同大小)。Katzman 引入「引導式提問」技術解決這個問題:不直接問「這是漏洞嗎」,而是先用低 temperature 模式強迫 LLM 用文字把資料流圖描述一遍——source 在哪裡宣告、大小是多少、有沒有被改變過——讓 LLM 在回答最終問題之前,先把關鍵資訊強制寫進自己的預測序列。實驗顯示,這個與問題本身完全無關的提問流程,反而讓 LLM 準確判斷出這是一個典型誤報。
最終系統 Valhalla 整合了從 GitHub API 下載 CodeQL 資料庫、預萃取 CSV、安全代理透過 MCP 伺服器查詢 CSV,以及帶引導式提問的提示管線。在 100 個最高星標 C 語言倉庫上實測,874 個問題經過過濾後剩 239 個(減少 73%),並從中確認了 Redis、LibreOffice、Linux kernel、FFmpeg、Red Hat、PyBullet 等多個真實 CVE,成本不到 80 美元。引導式提問的另一個優點是可以調整嚴格度——問題越具體,假陽性越少但可能遺漏真陽性;問題越通用,真陽性保留率高但需要更多後續人工確認,整體錯誤率約在 3%–5% 之間。
關鍵時刻
Pipeline v2帶時間戳的重點,會在逐字稿層級分析上線後產生。目前請先透過原始影片觀看。
事實查核
Pipeline v2說法查證是下一次管線升級的一部分。KeyFrame 只會顯示它真正能驗證的內容。


