codeql

codeql

熱門

使用 CodeQL 的跨程序資料流與污點追蹤分析來掃描程式碼庫中的安全漏洞。觸發條件包括:"run codeql"、"codeql scan"、"codeql analysis"、"build codeql database" 或 "find vulnerabilities with codeql"。支援「全跑模式 (run all)」(包含 security-and-quality + security-experimental 組合包)與「僅重要項目 (important only)」(高精準度安全檢測結果)兩種掃描模式。同時處理建立資料擴充模型(data extension models)以及解析 CodeQL SARIF 輸出的工作。

6367星標
548分支
更新於 2026/8/1
SKILL.md
唯讀
名稱
codeql
描述

使用 CodeQL 的跨程序資料流與污點追蹤分析來掃描程式碼庫中的安全漏洞。觸發條件包括:"run codeql"、"codeql scan"、"codeql analysis"、"build codeql database" 或 "find vulnerabilities with codeql"。支援「全跑模式 (run all)」(包含 security-and-quality + security-experimental 組合包)與「僅重要項目 (important only)」(高精準度安全檢測結果)兩種掃描模式。同時處理建立資料擴充模型(data extension models)以及解析 CodeQL SARIF 輸出的工作。

CodeQL 分析

支援的語言:Python、JavaScript/TypeScript、Go、Java/Kotlin、C/C++、C#、Ruby、Swift。

Skill 資源: 參考檔案與範本位於 {baseDir}/references/{baseDir}/workflows/

核心原則

  1. 資料庫品質絕不妥協。 能成功建置的資料庫並不代表品質合格。請務必執行品質評估(檢查檔案數量、基準程式碼行數 LoC、提取器錯誤),並與預期的原始碼檔案進行對比。快取的建置無法產生任何有用的提取結果。

  2. 資料擴充模型能補足 CodeQL 的遺漏。 即使是使用標準框架(如 Django、Spring、Express)的專案,通常也會對資料庫呼叫、請求解析或 Shell 執行進行自訂封裝。若跳過建立資料擴充(create-data-extensions)工作流程,將會漏掉專案特定程式碼路徑中的漏洞。

  3. 使用明確的查詢組合包引用,避免查詢被默然過濾。 切勿直接將套件名稱傳遞給 codeql database analyze——每個套件的 defaultSuiteFile 都會套用隱藏過濾條件,可能導致零分析結果。請務必生成自訂的 .qls 組合包檔案。

  4. 零檢測結果需要深入調查,而非慶祝。 零結果可能代表資料庫品質差、缺少模型、使用了錯誤的查詢套件,或是查詢組合包被悄悄過濾。在通報程式碼安全之前,請務必先進行調查。

  5. macOS Apple Silicon 針對編譯型語言需要變通方案。 Exit code 137 通常是 arm64e/arm64 架構不符合所致,並非建置失敗。在退回使用 build-mode=none 之前,請先嘗試 Homebrew arm64 工具或 Rosetta。

  6. 嚴格按部就班執行工作流程。 一旦選定了工作流程,請按部就班執行,切勿跳過任何階段。每個階段都是下一個階段的關卡——跳過品質評估或資料擴充,將導致分析結果不完整。

輸出目錄

所有產生的檔案(資料庫、建置日誌、診斷資訊、擴充模型、結果)均儲存在單一輸出目錄中。

  • 若使用者在提示詞中指定了輸出目錄,請將其作為 OUTPUT_DIR
  • 若未指定,預設為 ./static_analysis_codeql_1。若該目錄已存在,則遞增為 _2_3 等。

無論哪種情況,在寫入任何檔案之前,務必使用 mkdir -p 建立該目錄

# 解析輸出目錄
if [ -n "$USER_SPECIFIED_DIR" ]; then
  OUTPUT_DIR="$USER_SPECIFIED_DIR"
else
  BASE="static_analysis_codeql"
  N=1
  while [ -e "${BASE}_${N}" ]; do
    N=$((N + 1))
  done
  OUTPUT_DIR="${BASE}_${N}"
fi
mkdir -p "$OUTPUT_DIR"

輸出目錄會在任何工作流程執行前於開頭解析一次。所有工作流程都會接收 $OUTPUT_DIR 並將其產出物存放在該處:

$OUTPUT_DIR/
├── rulesets.txt                 # 已選取的查詢套件(於步驟 3 後記錄)
├── codeql.db/                   # CodeQL 資料庫(包含 codeql-database.yml 的目錄)
├── build.log                    # 建置日誌
├── codeql-config.yml            # 排除設定檔(直譯型語言)
├── diagnostics/                 # 診斷查詢與 CSV 檔
├── extensions/                  # 資料擴充模型 YAML 檔
├── raw/                         # 未過濾的分析輸出
│   ├── results.sarif
│   └── <mode>.qls
└── results/                     # 最終結果(僅重要模式會進行過濾,全跑模式則直接複製)
    └── results.sarif

資料庫搜尋偵測 (Database Discovery)

CodeQL 資料庫可透過其目錄內是否存在 codeql-database.yml 標記檔案來識別。搜尋現有資料庫時,務必收集所有符合的項目——因為可能存在先前執行或針對不同語言的多個資料庫。

偵測指令:

# 尋找所有 CodeQL 資料庫(頂層與一層子目錄深)
find . -maxdepth 3 -name "codeql-database.yml" -not -path "*/\.*" 2>/dev/null \
  | while read -r yml; do dirname "$yml"; done
  • $OUTPUT_DIR 內部: find "$OUTPUT_DIR" -maxdepth 2 -name "codeql-database.yml"
  • 專案全域(用於自動偵測): find . -maxdepth 3 -name "codeql-database.yml" —— 涵蓋專案頂層(./db-name/)與下一層子目錄(./subdir/db-name/)中的資料庫。不會往更深層搜尋。

切勿預設資料庫名稱一定是 codeql.db —— 請透過其標記檔案來搜尋識別。

當找到多個資料庫時:

針對每個搜尋到的資料庫,收集元資料以協助使用者選擇:

# 針對每個資料庫提取語言與建立時間
for db in $FOUND_DBS; do
  CODEQL_LANG=$(codeql resolve database --format=json -- "$db" 2>/dev/null | jq -r '.languages[0]')
  CREATED=$(grep '^creationMetadata:' -A5 "$db/codeql-database.yml" 2>/dev/null | grep 'creationTime' | awk '{print $2}')
  echo "$db — language: $CODEQL_LANG, created: $CREATED"
done

接著使用 AskUserQuestion 讓使用者選擇要使用哪一個資料庫,或是建置一個新的資料庫。若使用者已在提示詞中明確說明要使用哪個資料庫或要建立新資料庫,請跳過 AskUserQuestion

快速入門

針對常見使用情境(「掃描此程式碼庫中的漏洞」):

# 1. 確認 CodeQL 是否已安裝
if ! command -v codeql >/dev/null 2>&1; then
  echo "NOT INSTALLED: codeql binary not found on PATH"
else
  codeql --version || echo "ERROR: codeql found but --version failed (check installation)"
fi

# 2. 解析輸出目錄
BASE="static_analysis_codeql"; N=1
while [ -e "${BASE}_${N}" ]; do N=$((N + 1)); done
OUTPUT_DIR="${BASE}_${N}"; mkdir -p "$OUTPUT_DIR"

接著使用下方的工作流程執行完整管線:建置資料庫 → 建立資料擴充模型 → 執行分析

適用時機

  • 使用深度資料流分析來掃描程式碼庫中的安全漏洞
  • 從原始碼建置 CodeQL 資料庫(包含針對編譯型語言的建置能力)
  • 尋找需要跨程序污點追蹤或 AST/CFG 分析的複雜漏洞
  • 使用多個查詢套件(query packs)進行全面的安全稽核

不適用時機

  • 撰寫自訂查詢 - 請使用專用的查詢開發 skill
  • CI/CD 整合 - 請直接參考 GitHub Actions 官方文件
  • 快速模式搜尋 - 追求速度時請使用 Semgrep 或 grep
  • 缺乏編譯型語言的建置能力 - 請改為考慮 Semgrep
  • 單一檔案或輕量級分析 - 針對簡單的模式匹配,Semgrep 速度更快

應拒絕的合理化藉口

以下捷徑會導致遺漏檢測結果,請勿接受:

  • security-extended 就足夠了」 —— 它只是基礎門檻。請務必確認該語言是否有 Trail of Bits 套件與社群套件(Community Packs)可用。它們能捕捉到 security-extended 完全遺漏的漏洞類別。
  • security-and-quality 是最完整的組合包」 —— security-and-quality 排除所有 experimental/ 查詢路徑。在全跑模式(run-all)下,請同時匯入 security-and-qualitysecurity-experimental。視語言而定,差異可達 1 至 52 個查詢。
  • 「資料庫成功建置了,所以沒問題」 —— 資料庫成功建置並不代表提取品質良好。請務必執行品質評估,並將檔案數量與預期的原始碼檔案進行對比。
  • 「標準框架不需要資料擴充模型」 —— 即便是 Django/Spring 應用程式,也有 CodeQL 未建模的自訂封裝。跳過擴充模型意味著會遺漏漏洞。
  • 「對編譯型語言使用 build-mode=none 就好」 —— 這會導致分析極不完整。僅能作為最後的萬不得已手段。在 macOS 上,請先嘗試 arm64 工具鏈變通方案或 Rosetta。
  • 「在 macOS 上建置失敗,直接用 build-mode=none 吧」 —— Exit code 137 是由 arm64e/arm64 不相符造成的,並非根本上的建置失敗。請參閱 macos-arm64e-workaround.md
  • 「沒有檢出任何結果代表程式碼很安全」 —— 零檢出可能意味著資料庫品質差、缺少模型或用了錯誤的查詢套件。在回報安全之前請先調查。
  • 「我直接執行預設組合包就好了」 / 「我直接傳入套件名稱即可」 —— 每個套件的 defaultSuiteFile 都會套用隱藏過濾條件,且可能產生零結果。請務必使用明確的組合包引用。
  • 「我把檔案放在目前目錄就好」 —— 所有產生的檔案都必須放入 $OUTPUT_DIR。將檔案散落在工作目錄會導致無法清理,且有覆蓋先前執行結果的風險。
  • 「直接用我找到的第一個資料庫就好」 —— 可能存在針對不同語言或先前執行留下的多個資料庫。當找到一個以上的資料庫時,請向使用者展示所有選項。只有在使用者已指定要使用哪個資料庫時,才能跳過提示。
  • 「使用者說『掃描』,代表他們要我隨便挑一個資料庫」 —— 「掃描」不等於選擇資料庫。若存在多個資料庫且使用者未指定,請主動詢問。

工作流程選擇

本 Skill 包含三個工作流程。一旦選定了工作流程,請按部就班執行,切勿跳過任何階段。

工作流程 目的
build-database 依序使用建置方法建立 CodeQL 資料庫
create-data-extensions 為專案 API 偵測或生成資料擴充模型 (data extension models)
run-analysis 選擇規則集、執行查詢、處理結果

自動偵測邏輯

若使用者已明確指定要執行的操作(例如:「建置資料庫」、「對 ./my-db 執行分析」),請直接執行該工作流程。若使用者的提示詞已清楚展現意圖,請切勿呼叫 AskUserQuestion 進行資料庫選擇——例如:「建置一個新資料庫」、「分析 static_analysis_codeql_2 中的 codeql 資料庫」、「從頭執行完整掃描」。

遇到「測試 (test)」、「掃描 (scan)」、「分析 (analyze)」或類似指令時的預設管線: 先尋找現有的資料庫,再做出決定。

# 透過尋找 codeql-database.yml 標記檔案來偵測所有 CodeQL 資料庫
# 搜尋頂層目錄與一層子目錄深
FOUND_DBS=()
while IFS= read -r yml; do
  db_dir=$(dirname "$yml")
  codeql resolve database -- "$db_dir" >/dev/null 2>&1 && FOUND_DBS+=("$db_dir")
done < <(find . -maxdepth 3 -name "codeql-database.yml" -not -path "*/\.*" 2>/dev/null)

echo "Found ${#FOUND_DBS[@]} existing database(s)"
條件 動作
未找到任何資料庫 解析新的 $OUTPUT_DIR,執行建置 → 擴充 → 分析(完整管線)
找到一個資料庫 使用 AskUserQuestion:重複使用或建立新的?
找到多個資料庫 使用 AskUserQuestion:列出所有資料庫及其元資料,讓使用者選擇一個或建立新的
使用者已明確說明意圖 跳過 AskUserQuestion,直接依其指令執行

資料庫選擇提示

當找到現有資料庫且使用者未明確指定要使用哪一個時,請透過 AskUserQuestion 呈現:

header: "Existing CodeQL Databases"
question: "I found existing CodeQL database(s). What would you like to do?"
options:
  - label: "<db_path_1> (language: python, created: 2026-02-24)"
    description: "Reuse this database"
  - label: "<db_path_2> (language: cpp, created: 2026-02-23)"
    description: "Reuse this database"
  - label: "Build a new database"
    description: "Create a fresh database in a new output directory"

選擇之後:

  • 若使用者選擇現有資料庫:$OUTPUT_DIR 設定為其上層目錄(或包含它的目錄),將 $DB_NAME 設定為所選路徑,接著進行擴充 → 分析。
  • 若使用者選擇「建立新的」: 解析新的 $OUTPUT_DIR,執行建置 → 擴充 → 分析。

一般原則