static-analysis:把 CodeQL、Semgrep 与 SARIF 串成可复用的 SAST 工作流

前言

在仓库里做安全扫描,常见做法是各自装一套 CodeQL 或 Semgrep,记一堆 CLI 参数,再把多份 JSON/SARIF 手工合并。模型辅助编码时,更容易出现「漏关 telemetry」「规则集未经确认就扫」「构建失败却当成无漏洞」这类流程问题。

Trail of Bits 在 skills 市场里提供的 static-analysis 插件,把深度分析(CodeQL)、快速模式扫描(Semgrep)和结果处理(SARIF)写成一组 Agent Skill,并附带固定脚本与工作流命令。下面介绍它是什么、能做什么,以及如何安装与调用。

这是什么

static-analysis 是 Trail of Bits Skills Marketplace 里 Code Auditing 类的一个插件,定位为「静态分析工具包」:用 CodeQL、Semgrep 做漏洞发现,并用 SARIF 解析与合并统一结果形态。

维护方与出处:仓库 trailofbits/skills;插件 README 标注作者为 Axel Mierczuk、Paweł Płatek。CodeQL 与 Semgrep 相关实践与 Trail of Bits Testing Handbook 中的静态分析章节对齐。

插件内包含三个 Skill(名称即技能标识):

Skill 作用
codeql 过程间污点与数据流等深度安全分析
semgrep 基于规则集的快速模式扫描
sarif-parsing 解析、汇总、去重各工具输出的 SARIF

官方 Skill 目录分别为:

  • plugins/static-analysis/skills/codeql
  • plugins/static-analysis/skills/semgrep
  • plugins/static-analysis/skills/sarif-parsing

核心功能

CodeQL(codeql Skill)

面向需要构建数据库、跑查询包的场景,强调「库质量」与「显式查询套件」,而不是默认套件静默过滤。

已文档化的能力包括:

  1. 为 Python、JavaScript/TypeScript、Go、Java/Kotlin、C/C++、C#、Ruby、Swift 等语言建库并分析。
  2. 通过显式 .qls 引用查询包(如 security-extended、Trail of Bits、Community 等),输出 SARIF/CSV。
  3. 生成 data extension,覆盖项目自定义 API 的 source/sink。
  4. 构建后运行 check_db_quality.py、分析前校验 verify_query_suite.py,避免「零告警等于安全」的误判。
  5. 扫描模式:run all(security-and-quality + security-experimental)与 important only(高精度子集)。

无人值守构建可走工作流 /static-analysis:codeql-build,例如:

/static-analysis:codeql-build {"target": "/abs/path", "lang": "cpp"}

工作流会按构建方法阶梯(autobuild、自定义命令、多步、no-build)尝试,并在质量门槛未达标时返回明确状态。

Semgrep(semgrep Skill)

面向快速全库或规则集驱动的第一次静态扫描。设计要点是把「命令生成」交给脚本,减少模型手写 CLI 时漏掉安全约束。

  1. 检测语言与 Semgrep Pro 是否可用(Pro 用于跨文件污点分析)。
  2. 从内置与第三方规则集(文档要求包含 Trail of Bits、0xdea、Decurity 等)组计划,第三步必须经用户明确批准后再执行。
  3. 通过 scripts/run-scans.sh 批量执行扫描;强制 --metrics=off,输出写入独立 OUTPUT_DIR。
  4. 用 merge_sarif.py 合并为 results/results.sarif;支持 run-all 与 important-only 两种模式。

若不需要规则集审批闸门、希望端到端一键跑完,可用工作流:

/static-analysis:semgrep-scan {"target": "/abs/path", "mode": "run-all"}

该命令对目标目录只读(无 --autofix),写入仅限输出目录;若输出目录与扫描目标相同则拒绝执行。

SARIF(sarif-parsing Skill)

用于已有扫描产物时的后处理:理解 SARIF 2.1.0 结构、从 rule 继承 severity(CodeQL 依赖此行为)、用 jq 或 Python(pysarif、sarif-tools)做查询,以及多文件聚合与去重、CI 集成模式。

脚本与工作流

组件 说明
workflows/semgrep-scan.js 对应 /static-analysis:semgrep-scan,阶段:Detect → Select → Scan → Report
workflows/codeql-build.js 对应 /static-analysis:codeql-build,阶段:Detect → Build → Assess
skills/semgrep/scripts/run-scans.sh 根据选定规则集生成 semgrep 命令、克隆第三方规则仓库、批跑并写 scans.json
skills/semgrep/scripts/merge_sarif.py 合并分片 SARIF

官方说明:扫描阶段由工作流直接调用 shell 脚本,退出码与 findings 来自工具进程与 JSON,而非模型自报。

安装与启用

先向 Claude Code 或兼容市场添加 Trail of Bits 市场,再安装 static-analysis 插件。

Claude Code:添加市场

/plugin marketplace add trailofbits/skills

浏览并安装:

/plugin menu

安装 static-analysis 插件(插件 README 写法)

/plugin install trailofbits/skills/plugins/static-analysis

Codex CLI

codex plugin marketplace add trailofbits/skills
codex plugin list
codex plugin add <plugin-name>@trailofbits

将 <plugin-name> 替换为市场中的插件名(与仓库目录 static-analysis 对应)。Codex 文档称可直接兼容 Claude 插件市场,无需额外 sidecar 元数据。

本地开发时,在仓库父目录执行 /plugins marketplace add ./skills 可挂载本地市场副本。

运行前需在本机安装对应 CLI:Semgrep(semgrep --version)、CodeQL(codeql --version),以及文档中用于脚本与合并的 jq、uv 等。未在官方文档中单独列出的 IDE 集成方式,此处不展开。

典型用法

1. 让 Agent 按 Semgrep Skill 五步走(含审批)

在对话中说明要对某代码库做 Semgrep 安全扫描。Skill 会:

  1. 解析输出目录(默认 static_analysis_semgrep_1 递增命名)。
  2. 检测语言与 Pro 状态。
  3. 展示规则集与模式,等待明确「同意/继续」。
  4. 调用 run-scans.sh。
  5. 合并 SARIF 并汇报 scans.json 中的 failed、skipped。

目标路径应使用绝对路径;所有产物落在 $OUTPUT_DIR 下。

2. 工作流一键 Semgrep(无规则集审批)

适合已确认扫描范围、只需只读扫描的场景:

/static-analysis:semgrep-scan {"target": "/abs/path/to/repo", "mode": "run-all"}

mode 也可按 Skill 文档选择 important-only 等等价语义(以 references/scan-modes.md 为准)。

3. CodeQL 全链路或仅构建

完整分析通常走:建库 → data extensions → run-analysis 工作流;Quick Start 要求先确认 codeql、jq、uv 在 PATH 上。

仅把耗时的构建交给工作流时:

/static-analysis:codeql-build {"target": "/abs/path", "lang": "cpp"}

返回 no-method-succeeded 或 built-below-threshold 时,需在 Skill 流程里继续解读日志与质量脚本输出,而不是直接当作扫描完成。

4. 多工具结果合并

Semgrep 路径最终产物为 $OUTPUT_DIR/results/results.sarif。若还有 CodeQL 或其他 SARIF 输出,可启用 sarif-parsing Skill 做 severity 解析、去重与 CI 侧聚合。

适用场景与注意

适合:

  • 需要在 AI 辅助审计里系统化跑 SAST,且希望规则集、metrics、输出目录有固定约束。
  • 同一仓库既要 CodeQL 深度分析,又要 Semgrep 快速扫一遍,再统一成 SARIF。
  • 与同一市场里的 variant-analysis、semgrep-rule-creator 等技能串联(插件 README 已列出关联)。

限制与坑:

  1. Semgrep 无 Pro 时跨文件污点能力受限,文档建议此时考虑 CodeQL。
  2. CodeQL 对编译型语言依赖构建;macOS Apple Silicon 上 exit 137 等需按参考文档处理,不应默认 build-mode=none。
  3. 第三方规则集需要克隆仓库;run-scans.sh 失败时不应手工.subset 扫描冒充完整结果。
  4. /static-analysis:semgrep-scan 与 semgrep Skill 共用 references/,但前者跳过规则集审批;选型取决于你是否要在扫描前编辑规则列表。

插件自带 hermetic 测试(tests/run_scan_tests.sh、tests/run_workflow_tests.sh),用于约束脚本与工作流行为,本地改插件时可参考。

结尾

static-analysis 把专业 SAST 里重复出现的步骤——选规则、关 telemetry、批跑、合并 SARIF、CodeQL 建库与质量门禁——封装进 Skill 与固定工作流,让「让模型扫一遍仓库」更接近可审计的流程,而不是一次性 CLI 拼写。

插件与 Skill 源码:https://github.com/trailofbits/skills/tree/main/plugins/static-analysis
市场总览:https://github.com/trailofbits/skills

羽毛球分组比赛记分
小程序二维码

欢迎使用《羽毛球分组比赛记分》微信小程序

小夜