Semgrep Rule Creator
Overview
Create custom Semgrep rules to detect project-specific vulnerability patterns, enforce security policies, and build reusable detection logic for your organization's threat model.
Trigger
Use when asked to write Semgrep rules, create custom SAST rules, detect a specific vulnerability pattern, or build a detection library for code review automation.
Semgrep Rule Anatomy
rules:
- id: rule-id
patterns:
- pattern: |
<pattern-here>
message: |
<human-readable description>
severity: ERROR # ERROR, WARNING, INFO
languages: [python, javascript, java]
metadata:
cwe: "CWE-89"
owasp: "A1:2021"
confidence: HIGH
Pattern Syntax
Basic Patterns
$VAR— matches any expression, captures as metavariable$...ARGS— matches zero or more arguments (ellipsis)...— matches any sequence of statements
Pattern Operators
pattern— single pattern matchpatterns— all must match (AND)pattern-either— any must match (OR)pattern-not— must NOT matchpattern-inside— must be inside this contextpattern-not-inside— must NOT be inside this contextfocus-metavariable— restrict match to a specific capture
Metavariable Conditions
metavariable-regex:
metavariable: $FUNC
regex: '(exec|system|popen)'
metavariable-comparison:
metavariable: $SIZE
comparison: $SIZE < 0
Workflow
1. Identify the Pattern
- Find one or more real examples of the vulnerability in code
- Determine what makes the code dangerous vs. safe
- Identify common variations and aliases
2. Write a Minimal Pattern
Start with the simplest pattern that matches the bad case:
pattern: os.system($CMD)
3. Reduce False Positives
Add pattern-not for known-safe usages:
patterns:
- pattern: os.system($CMD)
- pattern-not: os.system("ls")
- pattern-not-inside: |
if $SAFE:
...
os.system($CMD)
4. Add Taint Tracking (for data flow)
mode: taint
pattern-sources:
- pattern: request.args.get(...)
pattern-sinks:
- pattern: os.system(...)
5. Test the Rule
semgrep --config=my-rule.yaml test-cases/
semgrep --test my-rule.yaml
Create test files:
# ruleid: my-rule
os.system(user_input) # should match
# ok: my-rule
os.system("safe-static-command") # should not match
6. Package for Distribution
Organize rules in a registry-compatible structure:
rules/
injection/
command-injection.yaml
sql-injection.yaml
crypto/
weak-hash.yaml
Output
Deliver:
.yamlrule file(s) ready to run withsemgrep --config- Test case files demonstrating true positives and true negatives
- Brief explanation of what each rule detects and why
Related Skills
static-code-analysis— broader static analysisc-security-review— C/C++ rulesdifferential-security-review— diff-based rules
GitNexus Index
This skill is indexed by GitNexus for knowledge graph traversal. Index path: /Users/localuser/.claude/skills/semgrep-rule-creator/.gitnexus Last indexed: 2026-05-23