Skip to content

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

FieldDescription
idUnique identifier for the rule
messageMessage shown to the user
severityLevel: ERROR, WARNING, INFO
languagesSupported languages
patternBasic pattern to search for
pattern-eitherList of patterns (any must match)
pattern-notPattern to exclude
pattern-insideContext to search within
pattern-not-insideContext to exclude
metavariable-patternConstraints on metavariables
metadataAdditional metadata (CWE, OWASP, etc.)
fixSuggested 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

AspectSimple YAMLSemgrep
ComplexityLowHigh
PerformanceHighMedium
FlexibilityLowHigh
PatternsSimpleComplex
ContextNoYes

Next steps

RootCause - Modular Static Analysis Engine