
codeql
热门利用 CodeQL 的过程间数据流与污点追踪分析能力,深度扫描代码库中的安全漏洞。当出现“run codeql”、“codeql scan”、“codeql analysis”、“build codeql database”或“find vulnerabilities with codeql”等指令时自动触发。支持“全量扫描”(包含 security-and-quality + security-experimental 查询集)与“仅看重点”(高置信度安全问题)扫描模式。同时支持创建数据扩展模型(Data Extension Models)并处理 CodeQL 的 SARIF 格式结果输出。
利用 CodeQL 的过程间数据流与污点追踪分析能力,深度扫描代码库中的安全漏洞。当出现“run codeql”、“codeql scan”、“codeql analysis”、“build codeql database”或“find vulnerabilities with codeql”等指令时自动触发。支持“全量扫描”(包含 security-and-quality + security-experimental 查询集)与“仅看重点”(高置信度安全问题)扫描模式。同时支持创建数据扩展模型(Data Extension Models)并处理 CodeQL 的 SARIF 格式结果输出。
CodeQL 分析
支持的语言:Python, JavaScript/TypeScript, Go, Java/Kotlin, C/C++, C#, Ruby, Swift。
Skill 资源: 参考文件和模板位于 {baseDir}/references/ 和 {baseDir}/workflows/。
核心原则
-
数据库质量是硬指标。 能成功编译构建的数据库,并不意味着质量达标。务必运行质量评估(检查文件数量、基线代码行数 LoC、提取器报错),并与预期源码文件做对比。如果是纯缓存构建,提取出的有用信息基本为零。
-
数据扩展(Data Extensions)能补齐 CodeQL 遗漏的盲区。 即便是使用标准框架(Django、Spring、Express)的项目,通常也有针对数据库调用、请求解析或 Shell 执行的自定义封装。如果跳过创建数据扩展工作流,就会漏掉项目专属代码路径中的漏洞。
-
显式引用查询集(Suite),防止查询规则被默默过滤。 切勿将 pack 名称直接传给
codeql database analyze—— 每个包自带的defaultSuiteFile会施加隐藏过滤规则,可能导致最终跑出 0 个结果。务必生成自定义的.qls查询集文件。 -
零漏洞需要排查,而不是庆祝。 扫描出 0 个结果,可能意味着数据库构建质量差、缺少数据模型、选错了查询包,或者是查询集被静默过滤了。在出具“代码安全”结论前,一定要排查清楚。
-
macOS Apple Silicon 编译型语言需要特殊变通方案。 出现退出码 137 是因为
arm64e/arm64架构不匹配,并不是构建本身失败。在退而求其次使用build-mode=none前,请先尝试 Homebrew arm64 工具链或 Rosetta 兼容模式。 -
严格按 Workflow 步骤执行。 一旦选定某种工作流,必须按部就班执行,不可跳过任何阶段。后一个阶段依赖前一个阶段的判定 —— 跳过质量评估或数据扩展,必然导致分析结果残缺。
输出目录
所有生成的文件(数据库、构建日志、诊断信息、数据扩展 YAML、结果)都会统一存放在同一个输出目录中。
- 如果用户在 Prompt 中指定了输出目录,直接将其作为
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
数据库发现机制
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 供用户选择使用哪个数据库,或是重新构建一个。如果用户已经在 Prompt 中明确指定了使用哪个数据库或要求新建,请直接跳过 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(语法树/控制流图)分析的复杂漏洞
- 使用多个查询包完成全方位的安全审计
不适用场景
- 编写自定义查询规则 - 建议使用专门的查询开发 Skill
- CI/CD 集成配置 - 建议直接查阅 GitHub Actions 官方文档
- 快速模式/匹配搜索 - 如追求速度建议使用 Semgrep 或 grep
- 编译型语言缺少编译构建环境 - 建议改用 Semgrep
- 单文件或轻量级分析 - 简单模式匹配使用 Semgrep 速度更快
必须拒绝的侥幸心理
以下偷懒或侥幸的借口会导致漏洞漏报,绝不可接受:
- “跑 security-extended 就够了” - 它只是保底基线。务必检查该语言是否有 Trail of Bits 扩展包或社区包可用,它们能覆盖
security-extended完全漏掉的漏洞类型。 - “security-and-quality 是涵盖最广的查询集” -
security-and-quality排除掉了所有experimental/(实验性)查询路径。对于全量扫描模式,需要同时引入security-and-quality和security-experimental。两者相差 1 到 52 条查询规则(取决于语言)。 - “数据库构建好了,所以质量没问题” - 能构建成功并不等于提取质量高。务必进行质量评估,并将提取的文件数与预期源码文件做比对。
- “标准框架不需要做数据扩展” - 即便是 Django/Spring 应用,也有 CodeQL 无法自动建模的自定义封装。跳过扩展意味着遗漏漏洞。
- “编译型语言用 build-mode=none 挺好的” - 这会导致分析结果严重残缺。仅可作为走投无路时的最终手段。在 macOS 上,请先尝试 arm64 工具链变通方案或 Rosetta。
- “在 macOS 上编译失败了,直接改用 build-mode=none 吧” - 退出码 137 是由于
arm64e/arm64架构不匹配导致的,并不是根本上的编译失败。详见 macos-arm64e-workaround.md。 - “零漏洞说明代码很安全” - 0 个结果往往意味着数据库质量差、缺失数据模型或选错了查询包。在报告代码安全前,务必深入排查。
- “我就跑默认查询集” / “我直接把包名传过去” - 每个包的
defaultSuiteFile都有隐式过滤规则,可能跑出 0 个结果。务必使用显式的.qls查询集引用。 - “我就把文件随便放在当前目录了” - 所有生成的文件必须存放在
$OUTPUT_DIR中。在工作目录散落文件会导致后期无法清理,且有覆盖此前运行结果的风险。 - “直接用找到的第一个数据库” - 现场可能存在不同语言或历次运行留下的多个数据库。只要发现多个,就应向用户展示所有选项。仅在用户明确指定时才跳过询问。
- “用户说了‘扫描’,意思就是让我随便挑个数据库” - “扫描”不等于挑选数据库。若存在多个数据库且用户未指定,必须进行询问确认。
工作流选择
本 Skill 包含三个工作流。一旦选定某个工作流,必须按部就班完成各个阶段,严禁跳步。
| 工作流 | 目的 |
|---|---|
| build-database | 按顺序尝试构建方法,创建 CodeQL 数据库 |
| create-data-extensions | 针对项目 API 检测或生成数据扩展模型 |
| run-analysis | 选择规则集、执行查询并处理分析结果 |
自动检测逻辑
如果用户明确指定了操作(例如“构建数据库”、“对 ./my-db 执行分析”),则直接执行对应工作流。如果用户的 Prompt 已经表达了明确意图(例如“重新建个数据库”、“分析 static_analysis_codeql_2 里的 codeql 数据库”、“从零开始全面扫描”),切勿调用 AskUserQuestion 询问数据库选择。
遇到“测试”、“扫描”、“分析”等通用指令时的默认流水线: 先搜索排查现有数据库,再决策下一步。
# 通过查找 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,依次执行 构建 → 扩展 → 分析(全流程) |
| 找到 1 个数据库 | 调用 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,依次执行 构建 → 扩展 → 分析。





