Skip to main content
Create custom Semgrep rules for detecting security vulnerabilities, bug patterns, and code quality issues using a rigorous test-driven workflow.

Overview

The Semgrep Rule Creator plugin guides you through creating production-quality Semgrep rules with proper testing and validation. It enforces a strict test-first methodology to ensure rules are accurate, maintainable, and free from false positives. Key capabilities:
  • Test-driven rule development (write tests first, then iterate)
  • AST analysis to craft precise patterns
  • Support for both taint mode (data flow) and pattern matching
  • Comprehensive reference documentation from Semgrep docs
  • Common vulnerability patterns by language

Installation

Prerequisites

  • Semgrep installed (pip install semgrep or brew install semgrep)

When to Use

Use this plugin when you need to:
  • Create custom Semgrep rules for detecting specific bug patterns
  • Write rules for security vulnerability detection
  • Build taint mode rules for data flow analysis
  • Develop pattern matching rules for code quality checks
  • Enforce coding standards with custom detections

When NOT to Use

Do NOT use this plugin for:
  • Running existing Semgrep rulesets (use semgrep scan instead)
  • General static analysis without custom rules (use the static-analysis plugin)

Core Workflow

The plugin enforces a strict 7-step workflow:
1

Analyze the Problem

Understand the bug pattern, target language, and determine whether to use taint mode or pattern matching.
2

Write Tests First

Create test file with vulnerable cases (ruleid:) and safe cases (ok:) before writing any rule code.
3

Analyze AST Structure

Run semgrep --dump-ast to understand how Semgrep parses the code.
4

Write the Rule

Create the YAML rule file using appropriate pattern operators.
5

Iterate Until Tests Pass

Run semgrep --test and fix issues until all tests pass.
6

Optimize the Rule

Remove redundancies and simplify patterns while keeping all tests passing.
7

Final Validation

Run final validation to confirm the rule works correctly.

Taint Mode vs Pattern Matching

When to Use Taint Mode (Prioritize)

Use taint mode for data flow issues where untrusted input reaches dangerous sinks:
Why prioritize taint mode? Pattern matching finds syntax but misses context. A pattern eval($X) matches both eval(user_input) (vulnerable) and eval("safe_literal") (safe). Taint mode tracks data flow, so it only alerts when untrusted data actually reaches the sink.

When to Use Pattern Matching

Use pattern matching for simple syntactic patterns without data flow requirements:

Output Structure

Each rule produces exactly 2 files in a directory named after the rule ID:

Example Rule

Here’s a complete example for detecting SQL injection in Python:
Run tests:
Expected output:

Key Commands

Strictness Principles

The plugin enforces strict quality standards:
Non-negotiable requirements:
  • Test-first is mandatory: Never write a rule without tests
  • 100% test pass required: “Most tests pass” is not acceptable
  • One YAML file = one Semgrep rule: Don’t combine multiple rules
  • No generic rules: Avoid generic pattern matching (languages: generic)
  • Forbidden annotations: todoruleid: and todook: are not allowed

Anti-Patterns to Avoid

Too Broad

Matches everything, useless for detection:

Missing Safe Cases

Leads to undetected false positives:

Overly Specific

Misses variations:

Rationalizations to Reject

When writing Semgrep rules, reject these common shortcuts:

Required Documentation

Before writing any rule, the plugin requires reading these Semgrep resources using WebFetch:
  1. Rule Syntax
  2. Pattern Syntax
  3. ToB Testing Handbook - Semgrep
  4. Constant Propagation
  5. Writing Rules Index
  • semgrep-rule-variant-creator - Port existing Semgrep rules to new target languages
  • static-analysis - General static analysis toolkit with Semgrep, CodeQL, and SARIF parsing
  • variant-analysis - Find similar vulnerabilities across codebases

Additional Resources

Author

Maciej Domanski