关于 opengrep-rule-generator
通过引导式问答或漏洞分析生成 opengrep/semgrep YAML 规则的技能,帮助安全从业者界定检测模式、选择规则模式并准备测试用例。
主要功能
- 01引导式规则范围问答
- 02基于 CVE、CWE 和 OWASP 生成
- 03Search、taint 与 regex 规则模式
- 04降低误报的指导
- 05生成正例与反例测试
适用场景
- 01为特定漏洞创建规则
- 02将 CVE 或 OWASP 类别转为检测规则
- 03扫描代码中的常见安全问题
- 04添加测试并调整规则精度
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ security-phoenix-demo/ security-skills-claude-code --skill opengrep-rule-generator安装后在 Claude Code 中输入/opengrep-rule-generator确认已加载。
附带文件OPENGREP_RULE_GENERATOR_PROMPT.mdRULES_SYNTAX.md
详细介绍
Opengrep 规则生成器
概述
通过协作式对话生成有效的 opengrep/semgrep YAML 规则。支持两种工作流:引导式(通过交互式问答了解要检测的内容)和漏洞驱动式(给出 CVE、OWASP 类别或漏洞描述后,自动生成规则)。
适用场景
- 用户说“创建规则”“编写规则”“生成规则”或“检测 [漏洞]”
- 用户提供 CVE、CWE 或 OWASP 参考信息,并希望生成检测规则
- 用户分享代码片段并询问“如何捕获这种模式?”
- 用户想扫描代码库,查找某一类漏洞
- 用户要求审计代码中的安全问题,并希望获得可复用的规则
流程
digraph rule_gen {
"User request" [shape=doublecircle];
"Has specific vulnerability?" [shape=diamond];
"Guided Discovery" [shape=box];
"Vulnerability-Driven" [shape=box];
"Gather context" [shape=box];
"Choose rule mode" [shape=diamond];
"Generate Search rule" [shape=box];
"Generate Taint rule" [shape=box];
"Present rule for review" [shape=box];
"User approves?" [shape=diamond];
"Write rule file" [shape=box];
"Generate test file" [shape=box];
"Validate with opengrep" [shape=doublecircle];
"User request" -> "Has specific vulnerability?";
"Has specific vulnerability?" -> "Vulnerability-Driven" [label="yes"];
"Has specific vulnerability?" -> "Guided Discovery" [label="no"];
"Guided Discovery" -> "Gather context";
"Vulnerability-Driven" -> "Gather context";
"Gather context" -> "Choose rule mode";
"Choose rule mode" -> "Generate Search rule" [label="pattern match"];
"Choose rule mode" -> "Generate Taint rule" [label="data flow"];
"Generate Search rule" -> "Present rule for review";
"Generate Taint rule" -> "Present rule for review";
"Present rule for review" -> "User approves?";
"User approves?" -> "Present rule for review" [label="revise"];
"User approves?" -> "Write rule file" [label="yes"];
"Write rule file" -> "Generate test file";
"Generate test file" -> "Validate with opengrep";
}
参考文档
生成任何规则之前,请先从这些项目文档中加载上下文:
| 文档 | 路径 | 加载时机 |
|---|---|---|
| 规则语法与模板 | docs/ai/RULES_SYNTAX.md | 始终加载 — 包含所有操作符、模板和语言 ID |
| 规则索引 | docs/ai/RULES_INDEX.md | 检查是否存在类似规则时 |
| 引擎内部机制 | docs/ai/RULES_ENGINE.md | 在 search 与 taint 模式之间进行选择时 |
还要搜索现有规则,查找类似模式:
semgrep-rules/semgrep-rules/<language>/— 社区规则semgrep-rules-trailbits/<language>/— Trail of Bits 规则
工作流 1:引导式探索
依次一次询问一个问题,以明确规则范围:
步骤 1 — 要检测什么?
What vulnerability, bug pattern, or coding anti-pattern do you want to detect?
Examples:
- "SQL injection in our Flask app"
- "Hardcoded secrets in config files"
- "Missing null checks after API calls"
- "Insecure deserialization"
- "Race conditions in Go goroutines"
步骤 2 — 使用什么语言和框架?
What programming language(s) and frameworks are involved?
I support 30+ languages including: python, javascript, typescript, java, go,
ruby, php, csharp, c, rust, scala, kotlin, swift, terraform/hcl, yaml,
dockerfile, solidity, and more. I also support 'generic' for config files
and 'regex' for raw text matching.
步骤 3 — 展示存在漏洞的代码
Can you show me an example of the VULNERABLE code you want to catch?
And if possible, also show the SAFE version (the fix)?
This helps me write precise patterns with fewer false positives.
步骤 4 — 用户输入从哪里进入?(如适用)
Does this vulnerability involve untrusted user input flowing into a dangerous function?
If yes, I'll use TAINT MODE (tracks data flow from sources to sinks).
If no, I'll use SEARCH MODE (structural pattern matching).
For taint mode, I need to know:
- Sources: Where does untrusted data come from? (HTTP requests, file reads, env vars, etc.)
- Sinks: Where is it dangerous? (SQL queries, system commands, file writes, etc.)
- Sanitizers: What makes the data safe? (escaping, validation, type casting, etc.)
步骤 5 — 严重性和范围
How severe is this issue?
- CRITICAL/ERROR: Exploitable vulnerability, must fix
- WARNING/MEDIUM: Likely vulnerability, should fix
- INFO/LOW: Code smell or audit flag
Should the rule apply to all files, or specific paths only?
工作流 2:漏洞驱动式生成
收到 CVE、CWE、OWASP 类别或漏洞描述时:
- 研究漏洞 — 使用下方的研究计划收集完整上下文
- 解析漏洞 — 提取:受影响的语言、存在漏洞的 API/模式、攻击途径、修复方法
- 检查现有规则 — 在
semgrep-rules/和semgrep-rules-trailbits/中搜索相关覆盖 - 确定规则模式:
- 数据从输入流向危险函数 → Taint 模式
- 危险函数调用或配置模式 → Search 模式
- 无需 AST 的文本/配置模式 → Regex/通用模式
- 生成规则 — 针对不同攻击变体,可能生成多条规则
- 附上说明,介绍每条规则能检测的内容及已知限制
漏洞研究计划
生成规则之前,请开展研究,确保覆盖全面。使用 WebSearch 和 WebFetch 工具。
阶段 1 — 了解漏洞:
- 搜索
"<CVE/CWE ID>" vulnerability details,查找官方描述 - 搜索
"<vulnerability type>" <language> exploit examples,查找真实攻击模式 - 从
https://cwe.mitre.org/data/definitions/<ID>.html获取 CWE 条目,了解分类体系、相关弱点和检测方法 - 获取相关类别的 OWASP 页面(例如
https://owasp.org/Top10/A03_2021-Injection/)
阶段 2 — 梳理特定语言的攻击面:
- 搜索
"<vulnerability>" <framework> cheat sheet site:cheatsheetseries.owasp.org - 搜索
"<vulnerability>" <framework> security best practices - 确定:入口点(源)、危险 API(汇)、安全替代方案(清理器)
- 搜索
"<vulnerable function>" CVE,查找展示该模式的真实 CVE
阶段 3 — 研究现有检测方案:
- 搜索
semgrep rule "<vulnerability type>" <language>,查找社区规则 - 在
semgrep-rules/和semgrep-rules-trailbits/目录中搜索现有规则 - 记录已覆盖的内容和仍存在的缺口
阶段 4 — 记录研究结果: 在规则文件顶部以 YAML 注释块的形式编写简短的研究摘要:
# Research: <vulnerability type> in <language/framework>
# Sources: <where untrusted data enters>
# Sinks: <where data becomes dangerous>
# Sanitizers: <what makes data safe>
# References researched:
# - <url1>
# - <url2>
# Coverage gaps found: <what existing rules miss>
模式选择指南
| 漏洞类型 | 规则模式 | 原因 |
|---|---|---|
| SQL 注入 | 污点 | 用户输入 → 查询函数 |
| XSS | 污点 | 用户输入 → HTML 输出 |
| 命令注入 | 污点 | 用户输入 → exec/system |
| SSRF | 污点 | 用户输入 → HTTP 请求 |
| 路径遍历 | 污点 | 用户输入 → 文件操作 |
| 硬编码密钥 | 搜索 + 正则表达式 | 对字面量进行模式匹配 |
| 不安全配置 | 搜索 | 配置中的结构模式 |
| 缺少身份验证检查 | 搜索(内部/外部) | 模式缺失 |
| 竞态条件 | 搜索(内部 + 外部) | goroutine/线程中的模式 |
| 弱加密 | 搜索 | 特定 API 调用 |
| 反序列化 | 搜索或污点 | 取决于是否由输入控制 |
| Terraform 配置错误 | 搜索 | HCL 结构模式 |
规则生成模板
生成规则时,始终输出以下完整结构:
rules:
- id: <company-or-project>-<language>-<vuln-type>
message: >-
<1-3 sentences: what was found, why it's dangerous, how to fix it>
severity: <ERROR|WARNING|INFO>
languages: [<language>]
metadata:
category: <security|correctness|best-practice|performance>
cwe:
- "CWE-XXX: <Description>"
owasp: # include if security rule
- "A0X:2021 - <Category>"
references:
- <url-to-documentation>
technology:
- <framework-or-library>
subcategory:
- <vuln|audit>
confidence: <HIGH|MEDIUM|LOW>
likelihood: <HIGH|MEDIUM|LOW>
impact: <HIGH|MEDIUM|LOW>
# ... pattern operators or taint spec ...
命名规范
规则 ID:<scope>-<language>-<vuln-type>[-<variant>]
myapp-python-sql-injectionmyapp-go-race-condition-map-writemyapp-java-spring-ssrf
消息质量
优质消息应包含:
- 检测内容(该模式)
- 危险原因(风险)
- 修复方法(补救措施)
message: >-
User input from `flask.request` is concatenated into a SQL query string
passed to `cursor.execute()`. This could allow SQL injection, letting an
attacker read or modify database contents. Use parameterized queries instead:
`cursor.execute("SELECT * FROM users WHERE id = %s", (user_id,))`.
测试文件生成
始终生成配套的测试文件,其中包含:
# === True Positives (MUST trigger) ===
# ruleid: <rule-id>
<vulnerable code example 1>
# ruleid: <rule-id>
<vulnerable code example 2 — different variant>
# === True Negatives (must NOT trigger) ===
# ok: <rule-id>
<safe code — using the recommended fix>
# ok: <rule-id>
<safe code — different safe pattern>
最低要求: 每条规则至少包含 2 个真阳性和 2 个真阴性案例。
高级模式示例集
检测缺失的安全检查(pattern-not-inside)
patterns:
- pattern: dangerous_operation(...)
- pattern-not-inside: |
if <... auth_check(...) ...>:
...
检测受污染的字符串拼接(taint + metavariable-regex)
mode: taint
pattern-sources:
- pattern: request.args.get(...)
pattern-sinks:
- patterns:
- pattern: |
"$SQLSTR" + ...
- metavariable-regex:
metavariable: $SQLSTR
regex: \s*(?i)(select|delete|insert|create|update|alter|drop)\b.*
检测弱配置值(metavariable-comparison)
patterns:
- pattern-inside: |
resource "aws_s3_bucket" "..." {
...
versioning { days = $DAYS }
...
}
- metavariable-comparison:
metavariable: $DAYS
comparison: $DAYS < 90
检测多种调用变体(pattern-either + metavariable-regex)
patterns:
- pattern-either:
- pattern: $OBJ.$METHOD(...)
- pattern: $MODULE.$METHOD(...)
- metavariable-regex:
metavariable: $METHOD
regex: (eval|exec|compile|unsafe_load)
使用类型约束进行检测(typed metavariables)
# Go: match only http.Request types
pattern: ($REQ : *http.Request).$FIELD
使用标签进行多步污点分析
mode: taint
pattern-sources:
- patterns:
- pattern: request.get_param(...)
label: USER_INPUT
- patterns:
- pattern: $X + $Y
label: CONCATENATED
requires: USER_INPUT
pattern-sinks:
- patterns:
- pattern: db.execute(...)
requires: CONCATENATED
减少误报
生成规则后,始终考虑添加:
- pattern-not — 排除安全变体(字面字符串使用
pattern-not: func("...", ...)) - pattern-not-inside — 排除安全上下文(位于 try/catch 中,或位于清理包装器中)
- metavariable-regex — 将元变量值限制为危险值
- 安全类型排除项 —
options: { taint_assume_safe_numbers: true, taint_assume_safe_booleans: true } - 日志/打印排除项 — 使用
pattern-not-inside: $LOG.info(...)避免标记日志记录
验证清单
最终确定任何规则之前:
- 规则 ID 唯一且符合 kebab-case 格式
-
languages字段与目标代码匹配 - 消息说明检测内容、危险原因和修复方法
- 元数据在适用情况下包含 CWE 和 OWASP
- 至少有 2 个真阳性测试用例
- 至少有 2 个真阴性测试用例
- 已考虑减少误报的方法(pattern-not、安全类型选项)
- 如可用,使用
opengrep scan --config <rule.yaml> <test-file>测试规则
批量生成
当被要求为一类漏洞生成规则时(例如,“适用于 Python Flask 的 OWASP Top 10”):
- 列出所有适用的漏洞类别
- 检查
semgrep-rules/中已有的覆盖情况 - 找出覆盖缺口
- 仅为缺口生成规则
- 以表格呈现:| 漏洞 | 是否已有规则? | 新规则 ID | 模式 |
规则生成方法
遵循以下系统化流程来生成高质量规则:
1. 深入理解漏洞
不要只根据函数名进行模式匹配。 要理解:
- 是什么导致了危险?(根本原因,而不是症状)
- 攻击场景是什么?(攻击者如何利用它?)
- 数据流是什么?(来源 → 转换 → 接收点)
- 所有变体有哪些?(字符串拼接、格式字符串、模板字面量、f-string)
- 安全替代方案有哪些?(参数化查询、模板引擎、转义函数)
2. 将现有规则作为模板进行研究
从头编写前,先搜索现有规则中的相似模式:
semgrep-rules/semgrep-rules/<language>/<framework>/security/
semgrep-rules-trailbits/<language>/
阅读质量最佳的规则,并借鉴其模式。现有规则可以展示:
- 每种框架的标准数据来源
- 哪些
metavariable-regex模式有助于减少误报 pattern-not排除项的组织方式- 应使用哪些元数据字段和 CWE/OWASP 映射
3. 构建源—汇—净化器映射
针对每种语言/框架,记录:
| 组件 | 示例 |
|---|---|
| 源(用户输入入口) | request.args、req.query、$_GET、params[:] |
| 汇(危险的输出位置) | res.send()、echo、innerHTML、cursor.execute() |
| 净化器(安全的转换) | escape()、htmlspecialchars()、parseInt()、模板引擎 |
| 传播器(数据结构流转) | StringBuilder.append()、HashMap.put()、array.push() |
4. 采用纵深防御模式编写规则
分层编写规则:
- 广泛的污点规则 — 捕获主要攻击向量
- 特定搜索规则 — 捕获危险的 API 滥用(例如,
dangerouslySetInnerHTML) - 配置/审计规则 — 标记有风险的配置(例如,
autoescape off)
5. 迭代减少误报
初步生成规则后:
- 思考可能触发规则的常见安全模式
- 添加
pattern-not,排除安全字面量、安全类型和日志记录 - 添加
pattern-not-inside,排除 try/catch 和验证封装 - 设置
taint_assume_safe_numbers: true和taint_assume_safe_booleans: true - 使用
metavariable-regex限定危险的方法名称
完整上下文:参考文档
生成规则时,以下文档包含完整的规则架构:
| 所需内容 | 查阅位置 |
|---|---|
| 所有模式运算符 | docs/ai/RULES_SYNTAX.md §3-5 |
| 污点模式规范(源/汇/净化器/传播器/标签) | docs/ai/RULES_SYNTAX.md §6 |
| 元变量条件(正则表达式、比较、类型、模式) | docs/ai/RULES_SYNTAX.md §4 |
| 所有受支持的语言 | docs/ai/RULES_SYNTAX.md §9 |
| 规则模板(8 个完整示例) | docs/ai/RULES_SYNTAX.md §12 |
| 引擎如何匹配模式 | docs/ai/RULES_ENGINE.md §2 |
| 污点分析的内部工作原理 | docs/ai/RULES_ENGINE.md §3 |
| 各语言现有规则的覆盖范围 | docs/ai/RULES_INDEX.md |
| CWE/OWASP 元数据规范 | docs/ai/RULES_SYNTAX.md §7 |
| 规则选项(引擎配置) | docs/ai/RULES_SYNTAX.md §8 |
生成规则目录
将生成的规则存放在 custom-rules/<vuln-type>/ 中,并附上测试文件:
custom-rules/
xss/
xss-python-flask.yaml # Rules
xss-python-flask.py # Test file
sqli/
sqli-java-spring.yaml
sqli-java-spring.java
应避免的常见错误
| 错误 | 修正方法 |
|---|---|
模式过于宽泛($FUNC(...)) | 添加 metavariable-regex 或 pattern-inside 进行限制 |
| 函数体中缺少省略号 | 在函数/类主体中使用 ...,以灵活匹配 |
忘记为安全变体添加 pattern-not | 始终考虑:安全代码是什么样的? |
| 语言 ID 错误 | 查看 docs/ai/RULES_SYNTAX.md 第 9 节,确认有效 ID |
| 污点分析未配置净化器 | 始终思考:是什么让这些数据变得安全?添加净化器。 |
| 将框架版本写死 | 使用 ... 编写与版本无关的模式 |
| 未测试否定用例 | 误报会摧毁信任——测试安全的代码路径 |