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 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.

15 stars

Best use case

semgrep is best used when you need a repeatable AI agent workflow instead of a one-off prompt.

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.

Teams using semgrep should expect a more consistent output, faster repeated execution, less prompt rewriting.

When to use this skill

  • You want a reusable workflow that can be run more than once with consistent structure.

When not to use this skill

  • You only need a quick one-off answer and do not need a reusable workflow.
  • You cannot install or maintain the underlying files, dependencies, or repository context.

Installation

Claude Code / Cursor / Codex

$curl -o ~/.claude/skills/semgrep/SKILL.md --create-dirs "https://raw.githubusercontent.com/sushichan044/dotfiles/main/.agents/skills/semgrep/SKILL.md"

Manual Installation

  1. Download SKILL.md from GitHub
  2. Place it in .claude/skills/semgrep/SKILL.md inside your project
  3. Restart your AI agent — it will auto-discover the skill

How semgrep Compares

Feature / AgentsemgrepStandard Approach
Platform SupportNot specifiedLimited / Varies
Context Awareness High Baseline
Installation ComplexityUnknownN/A

Frequently Asked Questions

What does this skill do?

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.

Where can I find the source code?

You can find the source code on GitHub using the link provided at the top of the page.

Related Guides

SKILL.md Source

# 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)

```bash
# 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

```bash
semgrep --config auto .                    # Auto-detect rules
```

## Using Rulesets

```bash
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

```bash
semgrep --config p/security-audit --sarif -o results.sarif .   # SARIF
semgrep --config p/security-audit --json -o results.json .     # JSON
```

## Scan Specific Paths

```bash
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

```python
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

```yaml
rules:
  - id: hardcoded-password
    languages: [python]
    message: "Hardcoded password detected: $PASSWORD"
    severity: ERROR
    pattern: password = "$PASSWORD"
```

## Quick Start: Taint Mode

```yaml
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:

```python
# 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:

```bash
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 <lang> <file>`         |
| Debug taint flow | `semgrep --dataflow-traces -f rule.yaml file` |

## Rule Creation Workflow

1. **Analyze the problem** - Understand the bug pattern, determine taint vs pattern approach
2. **Create test cases first** - Write `ruleid:` and `ok:` annotations before the rule
3. **Analyze AST** - Run `semgrep --dump-ast` to understand code structure
4. **Write the rule** - Start simple, iterate
5. **Test until 100% pass** - No "missed lines" or "incorrect lines"
6. **Optimize patterns** - Remove redundancies only after tests pass

**Output structure:**

```
<rule-id>/
├── <rule-id>.yaml     # Semgrep rule
└── <rule-id>.<ext>    # Test file
```

## Detailed References

**Official Semgrep Documentation:**

- [Rule Syntax](https://semgrep.dev/docs/writing-rules/rule-syntax) - Complete YAML structure, operators, and options
- [Rule Schema](https://github.com/semgrep/semgrep-interfaces/blob/main/rule_schema_v1.yaml) - Full JSON schema specification

**Local References:**

- [Workflow Guide](references/workflow.md) - Complete step-by-step rule creation process
- [Quick Reference](references/quick-reference.md) - Pattern operators and taint components

## Anti-Patterns to Avoid

**Too broad:**

```yaml
# BAD: Matches any function call
pattern: $FUNC(...)

# GOOD: Specific dangerous function
pattern: eval(...)
```

**Missing safe cases:**

```python
# BAD: Only tests vulnerable case
# ruleid: my-rule
dangerous(user_input)

# GOOD: Include safe cases
# ruleid: my-rule
dangerous(user_input)

# ok: my-rule
dangerous(sanitize(user_input))
```

## Rationalizations to Reject

| Shortcut                               | Why It's Wrong                                                                   |
| -------------------------------------- | -------------------------------------------------------------------------------- |
| "Semgrep found nothing, code is clean" | Semgrep is pattern-based; can't track complex cross-function data flow           |
| "The pattern looks complete"           | Untested rules have hidden false positives/negatives                             |
| "It matches the vulnerable case"       | Matching vulnerabilities is half the job; verify safe cases don't match          |
| "Taint mode is overkill"               | For injection vulnerabilities, taint mode gives better precision                 |
| "One test case is enough"              | Include edge cases: different coding styles, sanitized inputs, safe alternatives |

---

# CI/CD Integration

## GitHub Actions

```yaml
name: Semgrep

on:
  push:
    branches: [main]
  pull_request:
  schedule:
    - cron: "0 0 1 * *"

jobs:
  semgrep:
    runs-on: ubuntu-latest
    container:
      image: returntocorp/semgrep

    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Run Semgrep
        run: |
          if [ "${{ github.event_name }}" = "pull_request" ]; then
            semgrep ci --baseline-commit ${{ github.event.pull_request.base.sha }}
          else
            semgrep ci
          fi
        env:
          SEMGREP_RULES: >-
            p/security-audit
            p/owasp-top-ten
            p/trailofbits
```

---

# Resources

**Rule Writing:**

- Rule Syntax: https://semgrep.dev/docs/writing-rules/rule-syntax
- Pattern Syntax: https://semgrep.dev/docs/writing-rules/pattern-syntax
- Rule Schema: https://github.com/semgrep/semgrep-interfaces/blob/main/rule_schema_v1.yaml

**General:**

- Registry: https://semgrep.dev/explore
- Playground: https://semgrep.dev/playground
- Docs: https://semgrep.dev/docs/
- Trail of Bits Rules: https://github.com/trailofbits/semgrep-rules

Related Skills

typescript-performance

15
from sushichan044/dotfiles

Comprehensive TypeScript performance analysis and optimization. Use when users report slow TypeScript compilation, slow editor experience, or want to investigate TypeScript performance issues. This skill provides diagnostic tools, trace analysis workflows, and optimization strategies. Key triggers include mentions of slow builds, type-checking delays, tsc performance, editor lag with TypeScript, or requests to analyze/improve TypeScript performance. Always prioritize data-driven analysis using --extendedDiagnostics, --generateTrace, and TS Server logs before making optimization recommendations.

watch-ci

15
from sushichan044/dotfiles

CI を監視し、失敗したら自律的に修正してパスするまでループするスキル。push 後・PR 作成後・rebase 後に CI が通るか確認したいとき、CI が落ちていたら直してほしいとき、CI の結果を待ちたいときに使う。「CI 監視して」「CI が通るまで待って」「CI 直して」「push したので CI を見ておいて」など、CI の状態確認・自動修正が必要な場面では必ずこのスキルを呼び出すこと。

vue-style-guide

15
from sushichan044/dotfiles

Vue を書くときは基本的に参考にしてください。 個人的に気に入っている ubgeeei 氏の Vue.js のスタイルガイドです。

vitess

15
from sushichan044/dotfiles

Vitess best practices, query optimization, and connection troubleshooting for PlanetScale Vitess databases. Load when working with Vitess databases, sharding, VSchema configuration, keyspace management, or MySQL scaling issues.

triage-pr-reviews

15
from sushichan044/dotfiles

Triages unresolved PR review comments using gh-pr-reviews. Analyzes code context and classifies each comment as Agree / Partially Agree / Disagree. Walks through each comment one-by-one, asking the user what action to take. Use when the user wants to triage, review, or analyze unresolved PR comments.

terraform-test

15
from sushichan044/dotfiles

Comprehensive guide for writing and running Terraform tests. Use when creating test files (.tftest.hcl), writing test scenarios with run blocks, validating infrastructure behavior with assertions, mocking providers and data sources, testing module outputs and resource configurations, or troubleshooting Terraform test syntax and execution.

terraform-style-guide

15
from sushichan044/dotfiles

Generate Terraform HCL code following HashiCorp's official style conventions and best practices. Use when writing, reviewing, or generating Terraform configurations.

terraform-stacks

15
from sushichan044/dotfiles

Comprehensive guide for working with HashiCorp Terraform Stacks. Use when creating, modifying, or validating Terraform Stack configurations (.tfcomponent.hcl, .tfdeploy.hcl files), working with stack components and deployments from local modules, public registry, or private registry sources, managing multi-region or multi-environment infrastructure, or troubleshooting Terraform Stacks syntax and structure.

teach-impeccable

15
from sushichan044/dotfiles

One-time setup that gathers design context for your project and saves it to your AI config file. Run once to establish persistent design guidelines.

stacked-pr

15
from sushichan044/dotfiles

依存関係のある複数の PR を管理・同期するためのスキル。stacked PR のカスケード rebase、PR 間の依存検出、base branch 管理、CI の上流優先修正を行う。PR が別の PR に依存している状況全般で使う — cascade rebase、スタック sync、依存先 PR 更新後のメンテ、PR チェーンの整合性確認などをするときなど。

smart-compact

15
from sushichan044/dotfiles

セッションのコンテキストを分析し、重要な情報を保持するためのプロンプトを生成して /compact コマンドの実行を支援するスキル。コンテキストウィンドウが逼迫してきた時や、セッションを整理したい時に使用。

skill-creator

15
from sushichan044/dotfiles

Create new skills, modify and improve existing skills, and measure skill performance. Use when users want to create a skill from scratch, edit, or optimize an existing skill, run evals to test a skill, benchmark skill performance with variance analysis, or optimize a skill's description for better triggering accuracy.