name: semgrep-rule-creator description: 创建自定义Semgrep规则以检测安全漏洞、错误模式和代码模式。当编写Semgrep规则或构建自定义静态分析检测时使用。 allowed-tools:
- Bash
- Read
- Write
- Edit
- Glob
- Grep
- WebFetch
Semgrep规则创建器
创建生产质量的Semgrep规则,并进行适当的测试和验证。
何时使用
理想场景:
- 为特定错误模式编写Semgrep规则
- 编写规则以检测代码库中的安全漏洞
- 为数据流漏洞编写污点模式规则
- 编写规则以强制执行编码标准
何时不使用
请勿将此技能用于:
- 运行现有的Semgrep规则集
- 没有自定义规则的一般静态分析(使用
static-analysis技能)
需拒绝的合理化借口
在编写Semgrep规则时,拒绝以下常见捷径:
- “模式看起来完整” → 仍需运行
semgrep --test --config <rule-id>.yaml <rule-id>.<ext>进行验证。未经测试的规则可能存在隐藏的误报/漏报。 - “匹配了易受攻击的案例” → 匹配漏洞仅是工作的一半。需验证安全案例是否不匹配(误报会破坏信任)。
- “污点模式对此过于复杂” → 如果数据从用户输入流到危险接收器,污点模式比模式匹配提供更好的精确度。
- “一个测试足够” → 包括边缘情况:不同的编码风格、经过净化的输入、安全替代方案和边界条件。
- “我先优化模式” → 先编写正确的模式,所有测试通过后再优化。过早优化会导致回归。
- “AST转储太复杂” → AST揭示了Semgrep如何查看代码。跳过它会导致模式遗漏语法变化。
反模式
过于宽泛 - 匹配所有内容,对检测无用:
# 错误:匹配任何函数调用
pattern: $FUNC(...)
# 正确:特定的危险函数
pattern: eval(...)
测试中缺少安全案例 - 导致未检测到的误报:
# 错误:仅测试易受攻击的案例
# ruleid: my-rule
dangerous(user_input)
# 正确:包括安全案例以验证无误报
# ruleid: my-rule
dangerous(user_input)
# ok: my-rule
dangerous(sanitize(user_input))
# ok: my-rule
dangerous("hardcoded_safe_value")
模式过于具体 - 遗漏变体:
# 错误:仅匹配确切格式
pattern: os.system("rm " + $VAR)
# 正确:通过污点跟踪匹配所有os.system调用
mode: taint
pattern-sinks:
- pattern: os.system(...)
严格级别
此工作流是严格的 - 请勿跳过步骤:
- 先阅读文档:编写Semgrep规则前,请参见文档
- 测试优先是强制性的:切勿编写未经测试的规则
- 要求100%测试通过:“大多数测试通过”不可接受
- 优化在最后:仅在所有测试通过后简化模式
- 避免通用模式:规则必须具体,不匹配宽泛模式
- 优先污点模式:针对数据流漏洞
- 一个YAML文件 - 一个Semgrep规则:每个YAML文件必须仅包含一个Semgrep规则;不要将多个规则组合在单个文件中
- 无通用规则:当针对特定语言编写Semgrep规则时 - 避免通用模式匹配(
languages: generic) - 禁止
todook和todoruleid测试注释:测试文件中用于未来规则改进的todoruleid: <rule-id>和todook: <rule-id>注释是禁止的
概述
此技能指导创建用于检测安全漏洞和代码模式的Semgrep规则。规则是迭代创建的:分析问题、先写测试、分析AST结构、编写规则、迭代直到所有测试通过、优化规则。
方法选择:
- 污点模式(优先):数据流问题,其中不受信任的输入到达危险接收器
- 模式匹配:简单语法模式,无需数据流要求
为什么优先污点模式? 模式匹配找到语法但错过上下文。模式 eval($X) 匹配 eval(user_input)(易受攻击)和 eval("safe_literal")(安全)。污点模式跟踪数据流,因此仅当不受信任的数据实际到达接收器时才发出警报——显著减少注入漏洞的误报。
方法间迭代: 可以实验。如果从污点模式开始效果不佳(例如,污点传播不如预期,误报/漏报太多),切换到模式匹配。反之,如果模式匹配在安全案例上产生太多误报,尝试污点模式。目标是有效的规则——而非严格坚持一种方法。
输出结构 - 在名为rule-id的目录中恰好有2个文件:
<rule-id>/
├── <rule-id>.yaml # Semgrep规则
└── <rule-id>.<ext> # 带有ruleid/ok注释的测试文件
快速开始
rules:
- id: insecure-eval
languages: [python]
severity: HIGH
message: 用户输入传递给eval()允许代码执行
mode: taint
pattern-sources:
- pattern: request.args.get(...)
pattern-sinks:
- pattern: eval(...)
测试文件(insecure-eval.py):
# ruleid: insecure-eval
eval(request.args.get('code'))
# ok: insecure-eval
eval("print('safe')")
运行测试(从规则目录): semgrep --test --config <rule-id>.yaml <rule-id>.<ext>
快速参考
- 对于命令、模式运算符和污点模式语法,请参见quick-reference.md。
- 对于详细工作流和示例,您必须参见workflow.md
工作流
复制此清单并跟踪进度:
Semgrep规则进度:
- [ ] 步骤1:分析问题
- [ ] 步骤2:先写测试
- [ ] 步骤3:分析AST结构
- [ ] 步骤4:编写规则
- [ ] 步骤5:迭代直到所有测试通过(semgrep --test)
- [ ] 步骤6:优化规则(移除冗余,重新测试)
- [ ] 步骤7:最终运行
文档
必需:在编写任何规则之前,使用WebFetch阅读以下4个链接中的所有Semgrep文档: