agentsclimarketplace

Semgrep

Skill kpatryk/skills/skills/semgrep

AI skills

Install
npx -y skills add kpatryk/skills --skill semgrep

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

What its author says it does

Copied from the file, not written here

Comprehensive reference for Semgrep — the open-source static analysis tool that finds bugs, enforces code patterns, and detects security vulnerabilities across 30+ languages using semantic pattern matching. Use this skill whenever the user asks about running Semgrep scans, writing custom Semgrep rules, configuring Semgrep in CI/CD, interpreting scan results, using the Semgrep registry, setting up pre-commit hooks, or understanding Semgrep's YAML rule syntax. Trigger on any mention of semgrep, static analysis rules, custom SAST rules, code pattern matching, security scanning with semgrep, or semgrep integration.

The file declares its own license as MIT. That is the author’s claim about this one file, and it is not the same thing as the license GitHub reports for the repository, which is listed with the other numbers below.

SKILL.md

9.8 KB, as published. Nobody here has run it

Semgrep

Semgrep is a fast, open-source static analysis tool that finds bugs, security issues, and code quality problems by matching code patterns the way a developer thinks about code — not as plain text or AST dumps, but as structured code with semantic understanding. It supports 30+ languages and requires no compilation.

Official docs: https://semgrep.dev/docs/

Installation

# macOS
brew install semgrep

# pip (any platform)
python3 -m pip install semgrep

# confirm
semgrep --version

Core concepts

Semgrep works by matching patterns against an abstract syntax tree (AST), not raw text. This means foo(1, 2) and foo( 1, 2 ) are equivalent. Patterns can include:

  • Metavariables ($X, $VAR) — match any expression and bind it for reuse
  • Ellipsis (...) — match any sequence of arguments, statements, or characters
  • Typed metavariables ($TYPE $VAR) — language-specific type constraints

Running scans

Quick start (recommended)

# Scan current directory with auto-selected community rules
semgrep scan --config auto

# Scan a specific path
semgrep scan --config auto src/

# Use a registry ruleset
semgrep scan --config p/python src/
semgrep scan --config p/security-audit .
semgrep scan --config p/owasp-top-ten .
semgrep scan --config p/javascript .

Common scan flags

FlagDescription
-c / --configRules source: auto, p/<ruleset>, path to YAML, or URL
-e / --patternOne-shot pattern (ephemeral rule); requires --lang
-l / --langLanguage for --pattern scans (e.g. python, js, go)
--jsonMachine-readable JSON output
--sarifSARIF format (used by GitHub code scanning)
-o / --outputWrite results to a file instead of stdout
--severityFilter: ERROR, WARNING, INFO
--excludeGlob patterns to skip (e.g. --exclude='*.min.js')
--includeRestrict to matching paths
--no-git-ignoreScan gitignored files too
--timeoutPer-file timeout in seconds (default 5)
--metricsauto / on / off — telemetry control
-j / --jobsParallelism (default: ~85% of logical cores)
-v / --verboseShow which rules are running, parse errors, etc.
--dataflow-tracesShow how tainted data reaches findings (SARIF/text)
--autofixApply fix: patches from rules automatically

Ephemeral (one-shot) patterns

Great for quick checks without writing a YAML file:

# Find self-comparisons (likely bugs)
semgrep scan -e '$X == $X' --lang=python .

# Find any os.system call
semgrep scan -e 'os.system(...)' --lang=python .

# Find requests.get with verify=False
semgrep scan -e 'requests.get(..., verify=False, ...)' --lang=python .

Multiple configs at once

semgrep scan --config p/python --config rules/my-custom.yaml src/

Output to file

semgrep scan --config auto --json -o results.json .
semgrep scan --config auto --sarif -o results.sarif .

Popular registry rulesets

Find rulesets at https://semgrep.dev/r

ConfigWhat it scans
autoAuto-selects rules for detected languages (recommended)
p/pythonPython best practices and bugs
p/javascriptJavaScript / Node.js
p/typescriptTypeScript
p/goGo
p/javaJava
p/rubyRuby
p/rustRust
p/security-auditCross-language security findings
p/owasp-top-tenOWASP Top 10 categories
p/python-command-injectionPython command injection specifically
p/secretsHardcoded secrets and credentials
p/ciCI/CD configuration issues
p/terraformInfrastructure-as-code
p/dockerDockerfile issues

Writing custom rules

Rules live in YAML files. See references/rule-syntax.md for full reference.

Minimal rule

rules:
  - id: no-eval
    languages: [python]
    severity: ERROR
    message: "Avoid eval() — it executes arbitrary code. Use ast.literal_eval() for safe parsing."
    pattern: eval(...)

Patterns with AND logic (patterns)

rules:
  - id: unverified-db-query
    languages: [python]
    severity: WARNING
    message: "db_query called without verify=True"
    patterns:
      - pattern: db_query(...)
      - pattern-not: db_query(..., verify=True, ...)

OR logic (pattern-either)

rules:
  - id: weak-hash
    languages: [python]
    severity: ERROR
    message: "MD5 and SHA1 are cryptographically weak. Use SHA-256 or better."
    pattern-either:
      - pattern: hashlib.md5(...)
      - pattern: hashlib.sha1(...)

Scope restriction (pattern-inside / pattern-not-inside)

rules:
  - id: exec-in-request-handler
    languages: [python]
    severity: ERROR
    message: "Executing shell commands inside a Flask route is dangerous"
    patterns:
      - pattern: os.system(...)
      - pattern-inside: |
          @app.route(...)
          def $FUNC(...):
              ...

Auto-fix with fix:

rules:
  - id: use-subprocess-not-os-system
    languages: [python]
    severity: WARNING
    message: "Prefer subprocess.run() over os.system()"
    pattern: os.system($CMD)
    fix: subprocess.run($CMD, shell=True)

Metavariables and constraints

rules:
  - id: hardcoded-password-arg
    languages: [python]
    severity: ERROR
    message: "Hardcoded password passed as argument"
    patterns:
      - pattern: $FUNC(..., password=$PASS, ...)
      - metavariable-regex:
          metavariable: $PASS
          regex: '"[^"]+"'   # matches a string literal

Cross-statement tracking (taint analysis)

rules:
  - id: user-input-to-system
    languages: [python]
    severity: ERROR
    message: "User input reaches a shell command"
    mode: taint
    pattern-sources:
      - pattern: input(...)
    pattern-sinks:
      - pattern: os.system(...)

Rule with paths: restrictions

rules:
  - id: no-debug-print
    languages: [python]
    severity: INFO
    message: "Remove debug print statements before merging"
    pattern: print(...)
    paths:
      exclude:
        - tests/
        - scripts/

Ignoring findings

Inline suppression

result = os.system(cmd)  # nosem
result = os.system(cmd)  # nosem: rule-id-here

.semgrepignore file

Works like .gitignore:

# .semgrepignore
tests/
vendor/
*.min.js
generated/

CI/CD integration

GitHub Actions (OSS, no account required)

name: Semgrep
on:
  push:
    branches: [main]
  pull_request:

jobs:
  semgrep:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: returntocorp/semgrep-action@v1
        with:
          config: auto

GitHub Actions with SARIF (code scanning)

- name: Run Semgrep
  run: semgrep scan --config auto --sarif -o semgrep.sarif .

- name: Upload SARIF
  uses: github/codeql-action/upload-sarif@v3
  with:
    sarif_file: semgrep.sarif

semgrep ci (managed, requires SEMGREP_APP_TOKEN)

SEMGREP_APP_TOKEN=<token> semgrep ci

In CI, semgrep ci only reports findings introduced by the current PR/MR (differential scan).

Pre-commit hook

# .pre-commit-config.yaml
repos:
  - repo: https://github.com/returntocorp/semgrep
    rev: v1.127.0   # use latest tag from https://github.com/returntocorp/semgrep/releases
    hooks:
      - id: semgrep
        args: ['--config', 'auto', '--error']

The --error flag makes semgrep exit non-zero when findings exist, blocking the commit.


Output formats

FormatFlagUse case
Text (default)--textHuman reading
JSON--jsonScripts, parsing
SARIF--sarifGitHub/GitLab code scanning
JUnit XML--junit-xmlJenkins, CI test reports
GitLab SAST--gitlab-sastGitLab security dashboard
Emacs--emacsEmacs flycheck
Vim--vimVim ale/syntastic

Performance tips

  • Use --include='*.py' to restrict file types when scanning large repos
  • Avoid overly broad ... ellipsis in deeply-nested patterns — it can be slow
  • --timeout (default 5s per file) prevents runaway rules
  • Use -j to control parallelism; don't over-subscribe cores
  • .semgrepignore to skip vendored/generated directories
  • --exclude-minified-files to skip minified JS/CSS

Common pitfalls

  1. False positives with complex patterns: Use pattern-not and pattern-not-inside to narrow scope
  2. Missing matches due to equivalent syntax: Semgrep normalizes whitespace/parens, but not semantic aliases (e.g. open() vs Path.open())
  3. Metavariable scope: $X in one pattern is shared with $X in sibling patterns under patterns:
  4. Language mismatch: Always specify languages: correctly — wrong language = no matches
  5. Registry rules need internet: --config auto / --config p/X downloads rules; use --metrics=off for airgapped environments

Reference files

  • references/rule-syntax.md — Complete YAML rule syntax with all operators and metavariable operators
  • references/languages.md — All supported languages, file extensions, and languages: key values

Keep looking

Skills are one crate of 328,083. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.