Semgrep Rules
Semgrep rules provide advanced pattern-matching capabilities, supporting complex combinations and semantic analysis.
Basic structure
yaml
rules:
- id: "rule-id"
message: "Rule message"
severity: "WARNING"
languages: [rust]
pattern-either:
- pattern: "pattern1"
- pattern: "pattern2"
metadata:
cwe: "CWE-328: Use of Weak Hash"
confidence: HIGH
category: security
fix: "fix_suggestion"
Real example
yaml
rules:
- id: insecure-hashes
message: Detected cryptographically insecure hashing function
pattern-either:
- pattern: md2::Md2::new(...)
- pattern: md4::Md4::new(...)
- pattern: md5::Md5::new(...)
- pattern: sha1::Sha1::new(...)
metadata:
references:
- https://github.com/RustCrypto/hashes
- https://docs.rs/md2/latest/md2/
- https://docs.rs/md4/latest/md4/
- https://docs.rs/md5/latest/md5/
- https://docs.rs/sha-1/latest/sha1/
technology:
- rust
category: security
cwe: "CWE-328: Use of Weak Hash"
confidence: HIGH
likelihood: LOW
impact: MEDIUM
subcategory: audit
license: Semgrep Rules License v1.0. For more details, visit
semgrep.dev/legal/rules-license
vulnerability_class:
- Insecure Hashing Algorithm
languages:
- rust
severity: WARNING
fix: "sha2::Sha256::new(...)"
Pattern types
pattern
Basic pattern match:
yaml
pattern: "md5::Md5::new(...)"
pattern-either
Match any of the patterns:
yaml
pattern-either:
- pattern: "md5::Md5::new(...)"
- pattern: "sha1::Sha1::new(...)"
pattern-not
Exclude matches containing the pattern:
yaml
pattern-not: "safe_md5::Md5::new(...)"
pattern-inside
Match within a specific context:
yaml
pattern-inside: |
function $FUNC() {
...
}
pattern-not-inside
Exclude matches within a context:
yaml
pattern-not-inside: |
if (is_safe) {
...
}
metavariable-pattern
Apply additional constraints to metavariables:
yaml
metavariable-pattern:
metavariable: $VAR
pattern: "dangerous_*"
Key fields
Field | Description |
---|---|
id | Unique identifier for the rule |
message | Message shown to the user |
severity | Level: ERROR, WARNING, INFO |
languages | Supported languages |
pattern | Basic pattern to search for |
pattern-either | List of patterns (any must match) |
pattern-not | Pattern to exclude |
pattern-inside | Context to search within |
pattern-not-inside | Context to exclude |
metavariable-pattern | Constraints on metavariables |
metadata | Additional metadata (CWE, OWASP, etc.) |
fix | Suggested fix |
Use cases
Detecting dangerous functions
yaml
rules:
- id: dangerous-functions
message: Detected dangerous function call
pattern-either:
- pattern: "eval(...)"
- pattern: "exec(...)"
- pattern: "system(...)"
languages: [python]
severity: ERROR
Argument validation
yaml
rules:
- id: subprocess-shell
message: Using shell=True is dangerous
patterns:
- pattern: "subprocess.run(..., shell=True)"
- pattern-not-inside: |
if (is_safe_input($INPUT)) {
...
}
languages: [python]
severity: WARNING
Context analysis
yaml
rules:
- id: sql-injection
message: Potential SQL injection
patterns:
- pattern-inside: |
def $FUNC($REQUEST):
...
- pattern: "db.execute($QUERY)"
- metavariable-pattern:
metavariable: $QUERY
pattern: ".*\\+.*"
languages: [python]
severity: ERROR
Advantages
✅ Perfect for:
- Complex code patterns
- Semantic analysis
- Combinations of conditions
- Context analysis
- Advanced metavariables
❌ Limitations:
- Higher complexity
- Slower performance
- Steeper learning curve
Differences from simple YAML
Aspect | Simple YAML | Semgrep |
---|---|---|
Complexity | Low | High |
Performance | High | Medium |
Flexibility | Low | High |
Patterns | Simple | Complex |
Context | No | Yes |
Next steps
- YAML Rules - For simple patterns
- JSON Rules - For configurations
- OPA Rules - For advanced logic