Run Semgrep static analysis scan on a codebase using parallel subagents. Supports two scan modes — "run all" (full ruleset coverage) and "important only" (high-confidence security vulnerabilities). Automatically detects and uses Semgrep Pro for cross-file taint analysis when available. Use when asked to scan code for vulnerabilities, run a security audit with Semgrep, find bugs, or perform static analysis. Spawns parallel workers for multi-language codebases.
Semgrep 安全扫描
使用自动语言检测、通过 Task 子代理并行执行以及合并的 SARIF 输出来运行 Semgrep 扫描。
基本原则
- 始终使用
--metrics=off— Semgrep 默认发送遥测数据;--config auto也会回传。每个semgrep命令必须包含--metrics=off以防止安全审计期间数据泄露。 - 用户必须批准扫描计划(第 3 步是硬性门控) — 原始的“扫描此代码库”请求并非批准。展示确切的规则集、目标、引擎和模式;在启动扫描器之前等待明确的“是”/“继续”。
- 第三方规则集是必需的,而非可选 — Trail of Bits、0xdea 和 Decurity 规则能捕获官方注册表中缺失的漏洞。当检测到的语言匹配时,必须包含它们。
- 在单条消息中生成所有扫描 Task — 并行执行是核心性能优势。切勿顺序生成 Task;始终在一次响应中发出所有 Task 工具调用。
- 在扫描前始终检查 Semgrep Pro — Pro 支持跨文件污点跟踪,捕获约 250% 更多的真实阳性。跳过检查意味着静默遗漏关键的跨文件漏洞。
使用时机
- 代码库安全审计
- 在代码审查前发现漏洞
- 扫描已知的错误模式
- 初步静态分析
不使用时机
- 二进制分析 → 使用二进制分析工具
- 已有 Semgrep CI 配置 → 使用现有流水线
- 需要跨文件分析但无 Pro 许可证 → 考虑使用 CodeQL 作为替代
- 创建自定义 Semgrep 规则 → 使用
semgrep-rule-creator技能 - 将现有规则移植到其他语言 → 使用
semgrep-rule-variant-creator技能
输出目录
所有扫描结果、SARIF 文件和临时数据都存储在单个输出目录中。
- 如果用户在提示中指定了输出目录,则将其用作
OUTPUT_DIR。 - 如果未指定,则默认为
./static_analysis_semgrep_1。如果该目录已存在,则递增为_2、_3等。
在这两种情况下,始终使用 mkdir -p 创建目录,然后再写入任何文件。
# 解析输出目录
if [ -n "$USER_SPECIFIED_DIR" ]; then
OUTPUT_DIR="$USER_SPECIFIED_DIR"
else
BASE="static_analysis_semgrep"
N=1
while [ -e "${BASE}_${N}" ]; do
N=$((N + 1))
done
OUTPUT_DIR="${BASE}_${N}"
fi
mkdir -p "$OUTPUT_DIR/raw" "$OUTPUT_DIR/results"
输出目录在第 1 步开始时解析一次,并在后续所有步骤中使用。
$OUTPUT_DIR/
├── rulesets.txt # 已批准的规则集(第 3 步后记录)
├── raw/ # 每次扫描的原始输出(未过滤)
│ ├── python-python.json
│ ├── python-python.sarif
│ ├── python-django.json
│ ├── python-django.sarif
│ └── ...
└── results/ # 最终合并输出
└── results.sarif
前提条件
必需: Semgrep CLI(semgrep --version)。如果未安装,请参阅 Semgrep 安装文档。
可选: Semgrep Pro — 支持跨文件污点跟踪、过程间分析以及更多语言(Apex、C#、Elixir)。使用以下命令检查:
semgrep --pro --validate --config p/default 2>/dev/null && echo "Pro available" || echo "OSS only"
限制: OSS 模式无法跨文件跟踪数据流。Pro 模式使用 -j 1 进行跨文件分析(每个规则集较慢,但并行规则集可弥补)。
扫描模式
在工作流的第 2 步中选择模式。模式影响扫描器标志和后处理。
| 模式 | 覆盖范围 | 报告发现 |
|---|---|---|
| 全部运行 | 所有规则集,所有严重级别 | 全部 |
| 仅重要项 | 所有规则集,预过滤和后过滤 | 仅安全漏洞,中高置信度/影响 |
仅重要项 应用两层过滤:
- 预过滤:
--severity MEDIUM --severity HIGH --severity CRITICAL(CLI 标志) - 后过滤:JSON 元数据 — 仅保留
category=security、confidence∈{MEDIUM,HIGH}、impact∈{MEDIUM,HIGH}
有关元数据标准和 jq 过滤命令,请参阅 scan-modes.md。
编排架构
┌──────────────────────────────────────────────────────────────────┐
│ 主代理(本技能) │
│ 第 1 步:检测语言 + 检查 Pro 可用性 │
│ 第 2 步:选择扫描模式 + 规则集(参考:rulesets.md) │
│ 第 3 步:展示计划 + 规则集,获取批准 [⛔ 硬性门控] │
│ 第 4 步:生成并行扫描 Task(已批准的规则集 + 模式) │
│ 第 5 步:合并结果并报告 │
└──────────────────────────────────────────────────────────────────┘
│ 第 4 步
▼
┌─────────────────┐
│ 扫描 Task │
│ (并行) │
├─────────────────┤
│ Python 扫描器 │
│ JS/TS 扫描器 │
│ Go 扫描器 │
│ Docker 扫描器 │
└─────────────────┘
工作流
遵循 scan-workflow.md 中的详细工作流。 摘要:
| 步骤 | 操作 | 门控 | 关键参考 |
|---|---|---|---|
| 1 | 解析输出目录,检测语言 + Pro 可用性 | — | 使用 Glob,而非 Bash |
| 2 | 选择扫描模式 + 规则集 | — | rulesets.md |
| 3 | 展示计划,获取明确批准 | ⛔ 硬性 | AskUserQuestion |
| 4 | 生成并行扫描 Task | — | scanner-task-prompt.md |
| 5 | 合并结果并报告 | — | 合并脚本(如下) |
Task 强制执行: 调用时,创建 5 个具有 blockedBy 依赖关系的 Task(每个步骤阻塞前一个)。第 3 步是硬性门控 — 仅在用户明确批准后才标记完成。
合并命令(第 5 步):
uv run {baseDir}/scripts/merge_sarif.py $OUTPUT_DIR/raw $OUTPUT_DIR/results/results.sarif
代理
| 代理 | 工具 | 用途 |
|---|---|---|
static-analysis:semgrep-scanner |
Bash | 为语言类别执行并行 semgrep 扫描 |
在第 4 步生成 Task 子代理时使用 subagent_type: static-analysis:semgrep-scanner。
应拒绝的理由
| 捷径 | 错误原因 |
|---|---|
| “用户要求扫描,那就是批准” | 原始请求 ≠ 计划批准。展示计划,使用 AskUserQuestion,等待明确的“是” |
| “第 3 步 Task 正在阻塞,直接标记完成” | 对 Task 状态撒谎会破坏强制执行。仅在真正批准后标记完成 |
| “我已经知道他们想要什么” | 假设会导致扫描错误的目录/规则集。展示计划以供验证 |
| “只使用默认规则集” | 用户必须在扫描前看到并批准确切的规则集 |
| “未经询问添加额外规则集” | 未经同意修改已批准列表会破坏信任 |
| “第三方规则集是可选的” | Trail of Bits、0xdea、Decurity 能捕获官方注册表中缺失的漏洞 — 必需 |
| “使用 --config auto” | 发送指标;对规则集控制较少 |
| “一次一个 Task” | 破坏并行性;所有 Task 应一起生成 |
| “Pro 太慢,跳过 --pro” | 跨文件分析捕获 250% 更多的真实阳性;值得花费时间 |
| “Semgrep 原生支持 GitHub URL” | URL 处理在具有非标准 YAML 的仓库上失败;始终先克隆 |
| “清理是可选的” | 克隆的仓库会污染用户的工作区并随运行累积 |
“使用 . 或相对路径作为目标” |
子代理需要绝对路径以避免歧义 |
| “让用户稍后选择输出目录” | 输出目录必须在第 1 步解析,在任何文件创建之前 |
参考索引
| 文件 | 内容 |
|---|---|
| rulesets.md | 完整规则集目录和选择算法 |
| scan-modes.md | 预/后过滤标准和 jq 命令 |
| scanner-task-prompt.md | 生成扫描子代理的模板 |
| 工作流 | 用途 |
|---|---|
| scan-workflow.md | 完整的 5 步扫描执行过程 |
成功标准
- [ ] 输出目录已解析(用户指定或自动递增默认值)
- [ ] 所有生成的文件存储在
$OUTPUT_DIR内 - [ ] 已检测语言并统计文件数;Pro 状态已检查
- [ ] 用户已选择扫描模式(全部运行 / 仅重要项)
- [ ] 规则集包含所有检测语言的第三方规则
- [ ] 用户已明确批准扫描计划(第 3 步门控已通过)
- [ ] 所有扫描 Task 在单条消息中生成并完成
- [ ] 每个
semgrep命令都使用了--metrics=off - [ ] 已批准的规则集记录到
$OUTPUT_DIR/rulesets.txt - [ ] 每次扫描的原始输出存储在
$OUTPUT_DIR/raw/ - [ ]
results.sarif存在于$OUTPUT_DIR/results/中且为有效 JSON - [ ] 仅重要项模式:合并前应用后过滤;未过滤的结果保留在
raw/中 - [ ] 结果摘要按严重性和类别分类报告
- [ ] 克隆的仓库(如有)已从
$OUTPUT_DIR/repos/清理






