名称: semgrep 描述: 运行 Semgrep 静态分析扫描在代码库上使用并行子代理。自动检测并使用 Semgrep Pro 进行跨文件分析(当可用时)。当被要求扫描代码漏洞、使用 Semgrep 运行安全审计、查找错误或执行静态分析时使用。为多语言代码库和分类生成并行工作者。 允许工具:
- Bash
- Read
- Glob
- Grep
- Write
- Task
- AskUserQuestion
- TaskCreate
- TaskList
- TaskUpdate
- WebFetch
Semgrep 安全扫描
运行完整的 Semgrep 扫描,支持自动语言检测、通过 Task 子代理的并行执行和并行分类。自动使用 Semgrep Pro 进行跨文件污点分析(当可用时)。
先决条件
必需: Semgrep CLI
semgrep --version
如果未安装,请参见 Semgrep 安装文档。
可选: Semgrep Pro(用于跨文件分析和 Pro 语言)
# 检查 Semgrep Pro 引擎是否安装
semgrep --pro --validate --config p/default 2>/dev/null && echo "Pro 可用" || echo "仅 OSS"
# 如果已登录,安装/更新 Pro 引擎
semgrep install-semgrep-pro
Pro 启用功能:跨文件污点跟踪、过程间分析和附加语言(Apex, C#, Elixir)。
使用时机
- 代码库的安全审计
- 在代码审查前查找漏洞
- 扫描已知错误模式
- 首次静态分析
不使用时机
- 二进制分析 → 使用二进制分析工具
- 已配置 Semgrep CI → 使用现有流水线
- 需要跨文件分析但无 Pro 许可证 → 考虑 CodeQL 作为替代
- 创建自定义 Semgrep 规则 → 使用
semgrep-rule-creator技能 - 将现有规则移植到其他语言 → 使用
semgrep-rule-variant-creator技能
编排架构
此技能使用 并行 Task 子代理 以实现最大效率:
┌─────────────────────────────────────────────────────────────────┐
│ 主代理 │
│ 1. 检测语言 + 检查 Pro 可用性 │
│ 2. 基于检测选择规则集(参考:rulesets.md) │
│ 3. 呈现计划 + 规则集,获取批准 [⛔ 硬门] │
│ 4. 生成并行扫描 Tasks(使用已批准规则集) │
│ 5. 生成并行分类 Tasks │
│ 6. 收集并报告结果 │
└─────────────────────────────────────────────────────────────────┘
│ 步骤 4 │ 步骤 5
▼ ▼
┌─────────────────┐ ┌─────────────────┐
│ 扫描 Tasks │ │ 分类 Tasks │
│ (并行) │ │ (并行) │
├─────────────────┤ ├─────────────────┤
│ Python 扫描器 │ │ Python 分类器 │
│ JS/TS 扫描器 │ │ JS/TS 分类器 │
│ Go 扫描器 │ │ Go 分类器 │
│ Docker 扫描器 │ │ Docker 分类器 │
└─────────────────┘ └─────────────────┘
通过 Task 系统强制执行工作流
此技能使用 Task 系统 强制执行工作流合规性。调用时,创建以下任务:
TaskCreate: "检测语言和 Pro 可用性" (步骤 1)
TaskCreate: "基于检测选择规则集" (步骤 2) - blockedBy: 步骤 1
TaskCreate: "呈现计划与规则集,获取批准" (步骤 3) - blockedBy: 步骤 2
TaskCreate: "使用已批准规则集执行扫描" (步骤 4) - blockedBy: 步骤 3
TaskCreate: "分类发现" (步骤 5) - blockedBy: 步骤 4
TaskCreate: "报告结果" (步骤 6) - blockedBy: 步骤 5
强制门
| 任务 | 门类型 | 无法继续直到 |
|---|---|---|
| 步骤 3: 获取批准 | 硬门 | 用户明确批准规则集 + 计划 |
| 步骤 5: 分类 | 软门 | 所有扫描 JSON 文件存在 |
步骤 3 是硬门:仅在用户说“是”、“继续”、“批准”或等效后标记为 completed。
Task 流示例
1. 创建所有 6 个任务并带依赖关系
2. TaskUpdate 步骤 1 → in_progress,执行检测
3. TaskUpdate 步骤 1 → completed
4. TaskUpdate 步骤 2 → in_progress,选择规则集
5. TaskUpdate 步骤 2 → completed
6. TaskUpdate 步骤 3 → in_progress,呈现计划与规则集
7. 停止:等待用户响应(可能修改规则集)
8. 用户批准 → TaskUpdate 步骤 3 → completed
9. TaskUpdate 步骤 4 → in_progress(现在解除阻塞)
... 继续工作流
工作流
步骤 1: 检测语言和 Pro 可用性(主代理)
# 检查 Semgrep Pro 是否可用(非破坏性检查)
SEMGREP_PRO=false
if semgrep --pro --validate --config p/default 2>/dev/null; then
SEMGREP_PRO=true
echo "Semgrep Pro: 可用(跨文件分析启用)"
else
echo "Semgrep Pro: 不可用(OSS 模式,单文件分析)"
fi
# 通过文件扩展名查找语言
fd -t f -e py -e js -e ts -e jsx -e tsx -e go -e rb -e java -e php -e c -e cpp -e rs | \
sed 's/.*\.//' | sort | uniq -c | sort -rn
# 检查框架/技术
ls -la package.json pyproject.toml Gemfile go.mod Cargo.toml pom.xml 2>/dev/null
fd -t f "Dockerfile" "docker-compose" ".tf" "*.yaml" "*.yml" | head -20
映射发现到类别:
| 检测 | 类别 |
|---|---|
.py, pyproject.toml |
Python |
.js, .ts, package.json |
JavaScript/TypeScript |
.go, go.mod |
Go |
.rb, Gemfile |
Ruby |
.java, pom.xml |
Java |
.php |
PHP |
.c, .cpp |
C/C++ |
.rs, Cargo.toml |
Rust |
Dockerfile |
Docker |
.tf |
Terraform |
| k8s 清单 | Kubernetes |
步骤 2: 基于检测选择规则集
使用步骤 1 中检测到的语言和框架,按照 rulesets.md 中的 规则集选择算法 选择规则集。
算法涵盖:
- 安全基线(始终包含)
- 语言特定规则集
- 框架规则集(如果检测到)
- 基础设施规则集
- 必需 的第三方规则集(Trail of Bits, 0xdea, Decurity - 非可选)
- 注册表验证
输出: 结构化 JSON 传递给步骤 3 供用户审查:
{
"baseline": ["p/security-audit", "p/secrets"],
"python": ["p/python", "p/django"],
"javascript": ["p/javascript", "p/react", "p/nodejs"],
"docker": ["p/dockerfile"],
"third_party": ["https://github.com/trailofbits/semgrep-rules"]
}
步骤 3: 关键门 - 呈现计划并获取批准
⛔ 强制检查点 - 请勿跳过
此步骤需要在继续前明确用户批准。 用户可能在批准前修改规则集。
向用户呈现计划,并 明确列出规则集:
## Semgrep 扫描计划
**目标:** /path/to/codebase
**输出目录:** ./semgrep-results-001/
**引擎:** Semgrep Pro(跨文件分析) | Semgrep OSS(单文件)
### 检测到的语言/技术:
- Python(1,234 文件) - 检测到 Django 框架
- JavaScript(567 文件) - 检测到 React
- Dockerfile(3 文件)
### 要运行的规则集:
**安全基线(始终包含):**
- [x] `p/security-audit` - 全面安全规则
- [x] `p/secrets` - 硬编码凭证、API 密钥
**Python(1,234 文件):**
- [x] `p/python` - Python 安全模式
- [x] `p/django` - Django 特定漏洞
**JavaScript(567 文件):**
- [x] `p/javascript` - JavaScript 安全模式
- [x] `p/react` - React 特定问题
- [x] `p/nodejs` - Node.js 服务器端模式
**Docker(3 文件):**
- [x] `p/dockerfile` - Dockerfile 最佳实践
**第三方(自动包含用于检测到的语言):**
- [x] Trail of Bits 规则 - https://github.com/trailofbits/semgrep-rules
**可用但未选择:**
- [ ] `p/owasp-top-ten` - OWASP Top 10(与 security-audit 重叠)
### 执行策略:
- 生成 3 个并行扫描 Tasks(Python, JavaScript, Docker)
- 总规则集:9
- [如果 Pro] 跨文件污点跟踪启用
- 扫描代理:`static-analysis:semgrep-scanner`
- 分类代理:`static-analysis:semgrep-triager`
**想修改规则集?** 告诉我添加或移除哪些。
**准备扫描?** 说“继续”或“是”。
⛔ 停止:等待明确用户批准
呈现计划后:
-
如果用户想修改规则集:
- 添加请求的规则集到适当类别
- 移除请求的规则集
- 重新呈现更新后的计划
- 返回到等待批准
-
如果用户未响应,使用 AskUserQuestion:
"我已准备扫描计划,包含 9 个规则集(包括 Trail of Bits)。继续扫描吗?" 选项:["是,运行扫描", "先修改规则集"] -
有效批准响应:
- “是”、“继续”、“批准”、“开始”、“看起来不错”、“运行它”
-
仅在批准后并确认最终规则集后标记任务完成
-
不作为批准处理:
- 用户的原始请求(“扫描此代码库”)
- 沉默 / 无响应
- 关于计划的问题
预扫描检查清单
在标记步骤 3 完成前,验证:
- [ ] 向用户显示目标目录
- [ ] 显示引擎类型(Pro/OSS)
- [ ] 列出检测到的语言
- [ ] 所有规则集明确列出并带复选框
- [ ] 给用户机会修改规则集
- [ ] 用户明确批准(引用他们的确认)
- [ ] 捕获最终规则集列表用于步骤 4
- [ ] 列出代理类型:
static-analysis:semgrep-scanner和static-analysis:semgrep-triager
步骤 4: 生成并行扫描 Tasks
创建输出目录并带运行号以避免冲突,然后使用 步骤 3 中已批准的规则集 生成 Tasks:
# 查找下一个可用运行号
LAST=$(ls -d semgrep-results-[0-9][0-9][0-9] 2>/dev/null | sort | tail -1 | grep -o '[0-9]*$' || true)
NEXT_NUM=$(printf "%03d" $(( ${LAST:-0} + 1 )))
OUTPUT_DIR="semgrep-results-${NEXT_NUM}"
mkdir -p "$OUTPUT_DIR"
echo "输出目录: $OUTPUT_DIR"
在 SINGLE 消息中生成 N 个 Tasks(每个语言类别一个),使用 subagent_type: static-analysis:semgrep-scanner。
使用 scanner-task-prompt.md 中的扫描器任务提示模板。
示例 - 3 语言扫描(使用已批准规则集):
在 SINGLE 消息中生成这 3 个 Tasks:
-
Task: Python 扫描器
- 已批准规则集:p/python, p/django, p/security-audit, p/secrets, https://github.com/trailofbits/semgrep-rules
- 输出:semgrep-results-001/python-*.json
-
Task: JavaScript 扫描器
- 已批准规则集:p/javascript, p/react, p/nodejs, p/security-audit, p/secrets, https://github.com/trailofbits/semgrep-rules
- 输出:semgrep-results-001/js-*.json
-
Task: Docker 扫描器
- 已批准规则集:p/dockerfile
- 输出:semgrep-results-001/docker-*.json
步骤 5: 生成并行分类 Tasks
扫描 Tasks 完成后,使用 subagent_type: static-analysis:semgrep-triager 生成分类 Tasks(分类需要阅读代码上下文,而不仅仅是运行命令)。
使用 triage-task-prompt.md 中的分类任务提示模板。
步骤 6: 收集结果(主代理)
所有 Tasks 完成后,生成合并的 SARIF 并报告:
生成仅包含已分类真阳性发现的合并 SARIF:
uv run {baseDir}/scripts/merge_triaged_sarif.py [OUTPUT_DIR]
此脚本:
- 尝试使用 SARIF Multitool 进行合并(如果
npx可用) - 如果 Multitool 不可用,则回退到纯 Python 合并
- 读取所有
*-triage.json文件以提取真阳性发现 - 过滤合并的 SARIF 以仅包含已分类的真阳性
- 写入输出到
[OUTPUT_DIR]/findings-triaged.sarif
可选:安装 SARIF Multitool 以获得更好的合并质量:
npm install -g @microsoft/sarif-multitool
向用户报告:
## Semgrep 扫描完成
**扫描文件:** 1,804
**使用规则集:** 9(包括 Trail of Bits)
**总原始发现:** 156
**分类后:** 32 真阳性
### 按严重性:
- 错误:5
- 警告:18
- 信息:9
### 按类别:
- SQL 注入:3
- XSS:7
- 硬编码秘密:2
- 不安全配置:12
- 代码质量:8
结果写入:
- semgrep-results-001/findings-triaged.sarif(SARIF,仅真阳性)
- semgrep-results-001/*-triage.json(每个语言的分类详情)
- semgrep-results-001/*.json(原始扫描结果)
- semgrep-results-001/*.sarif(每个规则集的原始 SARIF)
常见错误
| 错误 | 正确方法 |
|---|---|
运行时不使用 --metrics=off |
始终使用 --metrics=off 以防止遥测 |
| 顺序运行规则集 | 使用 & 和 wait 并行运行 |
| 未将规则集限定到语言 | 使用 --include="*.py" 用于语言特定规则 |
| 报告原始发现未经分类 | 始终分类以移除假阳性 |
| 多语言单线程 | 为每个语言生成并行 Tasks |
| 顺序 Tasks | 在 SINGLE 消息中生成所有 Tasks 以实现并行 |
| Pro 可用时使用 OSS | 检查登录状态;使用 --pro 进行更深入分析 |
| 假设 Pro 不可用 | 始终在扫描前检查登录检测 |
限制
- OSS 模式: 无法跟踪跨文件数据流(使用
semgrep login登录并运行semgrep install-semgrep-pro以启用) - Pro 模式: 跨文件分析使用
-j 1(单作业),每个规则集较慢,但并行规则集补偿 - 分类需要阅读代码上下文 - 通过 Tasks 并行化
- 一些假阳性模式需要人为判断
代理
此插件为扫描和分类阶段提供两个专门代理:
| 代理 | 工具 | 目的 |
|---|---|---|
static-analysis:semgrep-scanner |
Bash | 执行并行 semgrep 扫描用于语言类别 |
static-analysis:semgrep-triager |
Read, Grep, Glob, Write | 通过阅读源上下文将发现分类为真/假阳性 |
在步骤 4 使用 subagent_type: static-analysis:semgrep-scanner 和在步骤 5 使用 subagent_type: static-analysis:semgrep-triager 当生成 Task 子代理时。
要拒绝的合理化
| 捷径 | 为什么错误 |
|---|---|
| “用户要求扫描,那就是批准” | 原始请求 ≠ 计划批准;用户必须确认特定参数。呈现计划,使用 AskUserQuestion,等待明确“是” |
| “步骤 3 任务阻塞,只需标记完成” | 谎报任务状态破坏强制执行。仅在真实批准后标记完成 |
| “我已经知道他们想要什么” | 假设导致扫描错误目录/规则集。呈现计划与所有参数以供验证 |
| “只需使用默认规则集” | 用户必须在扫描前看到并批准确切规则集 |
| “未经询问添加额外规则集” | 未经同意修改已批准列表破坏信任 |
| “跳过显示规则集列表” | 用户无法在看到要运行的内容前做出明智决定 |
| “第三方规则集可选” | Trail of Bits, 0xdea, Decurity 规则捕捉官方注册表中未包含的漏洞 - 当语言匹配时它们是必需的 |
| “跳过分类,报告所有” | 淹没用户噪音;真正问题被掩盖 |
| “一次运行一个规则集” | 浪费时间;并行执行更快 |
| “使用 --config auto” | 发送遥测;对规则集控制较少 |
| “稍后分类” | 无上下文的发现更难评估 |
| “一次一个 Task” | 破坏并行性;一起生成所有 Tasks |
| “Pro 太慢,跳过 --pro” | 跨文件分析捕捉 250% 更多真阳性;值得时间 |
| “不费心检查 Pro” | 缺少 Pro = 缺少关键跨文件漏洞 |
| “OSS 足够好” | OSS 错失文件间污点流;始终优先使用 Pro 当可用时 |