/semgrep
Run Semgrep static analysis scans and create custom detection rules. Use when asked to scan code with Semgrep, find security vulnerabilities, write custom YAML rules, or detect specific bug patterns. IMPORTANT: Also use this skill when users ask to 'scan for bugs', 'check code
$ npx -y skills add semgrep/skills --skill semgrep --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
- Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
- You can call itInvoke it directly when you want it.
- Slash command
/semgrep
Context preview
The summary Claude sees to decide when to auto-load this skill.
Run Semgrep static analysis scans and create custom detection rules. Use when asked to scan code with Semgrep, find security vulnerabilities, write custom YAML rules, or detect specific bug patterns. IMPORTANT: Also use this skill when users ask to 'scan for bugs', 'check code
SKILL.md
semgrep.SKILL.mdname: semgrep
description: "Run Semgrep static analysis scans and create custom detection rules. Use when asked to scan code with Semgrep, find security vulnerabilities, write custom YAML rules, or detect specific bug patterns. IMPORTANT: Also use this skill when users ask to 'scan for bugs', 'check code quality', 'find vulnerabilities', 'static analysis', 'lint for security', 'audit this code', or want to enforce coding standards — even if they don't mention Semgrep by name. Semgrep is the right tool for pattern-based code scanning across 30+ languages."
Semgrep Static Analysis
Fast, pattern-based static analysis for security scanning and custom rule creation.
MCP Tools Available
If Semgrep MCP tools are available in your environment, prefer them for scanning:
- **`semgrep_scan`** — Scan code files for security vulnerabilities using built-in rulesets. Pass absolute file paths and an optional config (e.g., `p/security-audit`, `auto`).
- **`semgrep_scan_with_custom_rule`** — Scan code with a custom YAML rule you've written. Pass code content inline along with the rule.
- **`semgrep_findings`** — Fetch existing findings from the Semgrep AppSec Platform for a repository.
- **`semgrep_rule_schema`** — Get the full schema for writing Semgrep rules.
- **`get_supported_languages`** — List all languages Semgrep supports.
When MCP tools aren't available, fall back to the CLI commands below.
When to Use Semgrep
**Ideal scenarios:**
- Quick security scans (minutes, not hours)
- Pattern-based bug and vulnerability detection
- Enforcing coding standards and best practices
- Finding known vulnerability patterns (OWASP, CWE)
- Creating custom detection rules for your codebase
- Data flow analysis with taint mode
Installation (CLI)
# pip (recommended)
python3 -m pip install semgrep
# Homebrew
brew install semgrep
# Docker
docker run --rm -v "${PWD}:/src" semgrep/semgrep semgrep --config auto /src---
Part 1: Running Scans
Quick Scan
semgrep --config auto . # Auto-detect rules
Using Rulesets
semgrep --config p/<RULESET> . # Single ruleset
semgrep --config p/security-audit --config p/trailofbits . # Multiple
| Ruleset | Description | |---------|-------------| | `p/default` | General security and code quality | | `p/security-audit` | Comprehensive security rules | | `p/owasp-top-ten` | OWASP Top 10 vulnerabilities | | `p/cwe-top-25` | CWE Top 25 vulnerabilities | | `p/trailofbits` | Trail of Bits security rules | | `p/python` | Python-specific | | `p/javascript` | JavaScript-specific | | `p/golang` | Go-specific |
Output Formats
semgrep --config p/security-audit --sarif -o results.sarif . # SARIF
semgrep --config p/security-audit --json -o results.json . # JSON
Scan Specific Paths
semgrep --config p/python app.py # Single file
semgrep --config p/javascript src/ # Directory
semgrep --config auto --include='**/test/**' . # Include tests
Configuration
.semgrepignore
tests/fixtures/
**/testdata/
generated/
vendor/
node_modules/
Suppress False Positives
password = get_from_vault() # nosemgrep: hardcoded-password
dangerous_but_safe() # nosemgrep
---
Part 2: Creating Custom Rules
When to Create Custom Rules
- Detecting project-specific vulnerability patterns
- Enforcing internal coding standards
- Building security checks for custom frameworks
- Creating taint-mode rules for data flow analysis
Approach Selection
| Approach | Use When | |----------|----------| | **Taint mode** | Data flows from untrusted source to dangerous sink (injection vulnerabilities) | | **Pattern matching** | Syntactic patterns without data flow requirements (deprecated APIs, hardcoded values) |
**Prioritize taint mode** for injection vulnerabilities. Pattern matching alone can't distinguish between `eval(user_input)` (vulnerable) and `eval("safe_literal")` (safe).
Quick Start: Pattern Matching
rules:
- id: hardcoded-password
languages: [python]
message: "Hardcoded password detected: $PASSWORD"
severity: ERROR
pattern: password = "$PASSWORD"Quick Start: Taint Mode
rules:
- id: command-injection
languages: [python]
message: User input flows to command execution
severity: ERROR
mode: taint
pattern-sources:
- pattern: request.args.get(...)
- pattern: request.form[...]
pattern-sinks:
- pattern: os.system(...)
- pattern: subprocess.call($CMD, shell=True, ...)
pattern-sanitizers:
- pattern: shlex.quote(...)Pattern Syntax Quick Reference
| Syntax | Description | Example | |--------|-------------|---------| | `...` | Match anything | `func(...)` | | `$VAR` | Capture metavariable | `$FUNC($INPUT)` | | `<... ...>` | Deep expression match | `<... user_input ...>` |
| Operator | Description | |----------|-------------| | `pattern` | Match exact pattern | | `patterns` | All must match (AND) | | `pattern-either` | Any matches (OR) | | `pattern-not` | Exclude matches | | `pattern-inside` | Match only inside context | | `pattern-not-inside` | Match only outside context | | `metavariable-regex` | Regex on captured value |
Testing Rules
**Test-first is mandatory.** Create test files with annotations:
# test_rule.py
def test_vulnerable():
user_input = request.args.get("id")
# ruleid: my-rule-id
cursor.execute("SELECT * FROM users WHERE id = " + user_input)
def test_safe():
user_input = request.args.get("id")
# ok: my-rule-id
cursor.execute("SELECT * FROM users WHERE id = ?", (user_input,))Run tests:
semgrep --test --config rule.yaml test-file
Command Reference
| Task | Command | |------|---------| | Run tests | `semgrep --test --config rule.yaml test-file` | | Validate YAML | `semgrep --validate --config rule.yaml` | | Dump AST | `semgrep --dump-ast -l <l
Read more
name: semgrep description: "Run Semgrep static analysis scans and create custom detection rules. Use when asked to scan code with Semgrep, find security vulnerabilities, write custom YAML rules, or detect specific bug patterns. IMPORTANT: Also use this skill when users ask to 'scan for bugs', 'check code quality', 'find vulnerabilities', 'static analysis', 'lint for security', 'audit this code', or want to enforce coding standards — even if they don't mention Semgrep by name. Semgrep is the right tool for pattern-based code scanning across 30+ languages."
Semgrep Static Analysis
Fast, pattern-based static analysis for security scanning and custom rule creation.
MCP Tools Available
If Semgrep MCP tools are available in your environment, prefer them for scanning:
- **`semgrep_scan`** — Scan code files for security vulnerabilities using built-in rulesets. Pass absolute file paths and an optional config (e.g., `p/security-audit`, `auto`).
- **`semgrep_scan_with_custom_rule`** — Scan code with a custom YAML rule you've written. Pass code content inline along with the rule.
- **`semgrep_findings`** — Fetch existing findings from the Semgrep AppSec Platform for a repository.
- **`semgrep_rule_schema`** — Get the full schema for writing Semgrep rules.
- **`get_supported_languages`** — List all languages Semgrep supports.
When MCP tools aren't available, fall back to the CLI commands below.
When to Use Semgrep
**Ideal scenarios:**
- Quick security scans (minutes, not hours)
- Pattern-based bug and vulnerability detection
- Enforcing coding standards and best practices
- Finding known vulnerability patterns (OWASP, CWE)
- Creating custom detection rules for your codebase
- Data flow analysis with taint mode
Installation (CLI)
# pip (recommended)
python3 -m pip install semgrep
# Homebrew
brew install semgrep
# Docker
docker run --rm -v "${PWD}:/src" semgrep/semgrep semgrep --config auto /src---
Part 1: Running Scans
Quick Scan
semgrep --config auto . # Auto-detect rules
Using Rulesets
semgrep --config p/<RULESET> . # Single ruleset semgrep --config p/security-audit --config p/trailofbits . # Multiple
| Ruleset | Description | |---------|-------------| | `p/default` | General security and code quality | | `p/security-audit` | Comprehensive security rules | | `p/owasp-top-ten` | OWASP Top 10 vulnerabilities | | `p/cwe-top-25` | CWE Top 25 vulnerabilities | | `p/trailofbits` | Trail of Bits security rules | | `p/python` | Python-specific | | `p/javascript` | JavaScript-specific | | `p/golang` | Go-specific |
Output Formats
semgrep --config p/security-audit --sarif -o results.sarif . # SARIF semgrep --config p/security-audit --json -o results.json . # JSON
Scan Specific Paths
semgrep --config p/python app.py # Single file semgrep --config p/javascript src/ # Directory semgrep --config auto --include='**/test/**' . # Include tests
Configuration
.semgrepignore
tests/fixtures/ **/testdata/ generated/ vendor/ node_modules/
Suppress False Positives
password = get_from_vault() # nosemgrep: hardcoded-password dangerous_but_safe() # nosemgrep
---
Part 2: Creating Custom Rules
When to Create Custom Rules
- Detecting project-specific vulnerability patterns
- Enforcing internal coding standards
- Building security checks for custom frameworks
- Creating taint-mode rules for data flow analysis
Approach Selection
| Approach | Use When | |----------|----------| | **Taint mode** | Data flows from untrusted source to dangerous sink (injection vulnerabilities) | | **Pattern matching** | Syntactic patterns without data flow requirements (deprecated APIs, hardcoded values) |
**Prioritize taint mode** for injection vulnerabilities. Pattern matching alone can't distinguish between `eval(user_input)` (vulnerable) and `eval("safe_literal")` (safe).
Quick Start: Pattern Matching
rules:
- id: hardcoded-password
languages: [python]
message: "Hardcoded password detected: $PASSWORD"
severity: ERROR
pattern: password = "$PASSWORD"Quick Start: Taint Mode
rules:
- id: command-injection
languages: [python]
message: User input flows to command execution
severity: ERROR
mode: taint
pattern-sources:
- pattern: request.args.get(...)
- pattern: request.form[...]
pattern-sinks:
- pattern: os.system(...)
- pattern: subprocess.call($CMD, shell=True, ...)
pattern-sanitizers:
- pattern: shlex.quote(...)Pattern Syntax Quick Reference
| Syntax | Description | Example | |--------|-------------|---------| | `...` | Match anything | `func(...)` | | `$VAR` | Capture metavariable | `$FUNC($INPUT)` | | `<... ...>` | Deep expression match | `<... user_input ...>` |
| Operator | Description | |----------|-------------| | `pattern` | Match exact pattern | | `patterns` | All must match (AND) | | `pattern-either` | Any matches (OR) | | `pattern-not` | Exclude matches | | `pattern-inside` | Match only inside context | | `pattern-not-inside` | Match only outside context | | `metavariable-regex` | Regex on captured value |
Testing Rules
**Test-first is mandatory.** Create test files with annotations:
# test_rule.py
def test_vulnerable():
user_input = request.args.get("id")
# ruleid: my-rule-id
cursor.execute("SELECT * FROM users WHERE id = " + user_input)
def test_safe():
user_input = request.args.get("id")
# ok: my-rule-id
cursor.execute("SELECT * FROM users WHERE id = ?", (user_input,))Run tests:
semgrep --test --config rule.yaml test-file
Command Reference
| Task | Command | |------|---------| | Run tests | `semgrep --test --config rule.yaml test-file` | | Validate YAML | `semgrep --validate --config rule.yaml` | | Dump AST | `semgrep --dump-ast -l <l
A collection of skills for AI coding agents. Skills are packaged instructions and scripts that extend agent capabilities. This should be considered beta-level software; it's primarily generated by transforming open-source Semgrep rules into skill format.
Repo: semgrep/skills
Other skills on semgrep-skills.
- /code-security
Security guidelines for writing secure code. Use when writing code, reviewing code for vulnerabilities, or asking about secure coding practices like 'check for SQL injection' or 'review security'. IMPORTANT: Always consult this skill when writing or reviewing any code that
Open skill - /llm-security
Security guidelines for LLM applications based on OWASP Top 10 for LLM 2025. Use when building LLM apps, reviewing AI security, implementing RAG systems, or asking about LLM vulnerabilities like 'prompt injection' or 'check LLM security'. IMPORTANT: Always consult this skill
Open skill

