semgrep

Par semgrep · skills

Exécuter des analyses statiques Semgrep et créer des règles de détection personnalisées. À utiliser lorsqu'on vous demande de scanner du code avec Semgrep, de trouver des vulnérabilités de sécurité, d'écrire des règles YAML personnalisées, ou de détecter des patterns de bugs spécifiques. IMPORTANT : Utilisez également cette compétence lorsque les utilisateurs demandent à « scanner les bugs », « vérifier la qualité du code », « trouver des vulnérabilités », « analyse statique », « audit de sécurité », « auditer ce code », ou souhaitent appliquer des normes de codage — même s'ils ne mentionnent pas Semgrep par son nom. Semgrep est l'outil adapté pour le scanning de code basé sur des patterns dans plus de 30 langages.

npx skills add https://github.com/semgrep/skills --skill semgrep

Semgrep Static Analysis

Analyse statique rapide basée sur des motifs pour le scanning de sécurité et la création de règles personnalisées.

Outils MCP disponibles

Si les outils MCP Semgrep sont disponibles dans votre environnement, préférez-les pour le scanning :

  • semgrep_scan — Scannez les fichiers de code pour les vulnérabilités de sécurité à l'aide des ensembles de règles intégrés. Passez des chemins de fichiers absolus et une configuration optionnelle (par exemple, p/security-audit, auto).
  • semgrep_scan_with_custom_rule — Scannez le code avec une règle YAML personnalisée que vous avez écrite. Passez le contenu du code en ligne avec la règle.
  • semgrep_findings — Récupérez les résultats existants de Semgrep AppSec Platform pour un repository.
  • semgrep_rule_schema — Obtenez le schéma complet pour écrire des règles Semgrep.
  • get_supported_languages — Listez tous les langages supportés par Semgrep.

Quand les outils MCP ne sont pas disponibles, utilisez les commandes CLI ci-dessous.

Quand utiliser Semgrep

Scénarios idéaux :

  • Scans de sécurité rapides (minutes, pas heures)
  • Détection de bugs et vulnérabilités basée sur des motifs
  • Application des standards de codage et bonnes pratiques
  • Recherche de motifs de vulnérabilités connues (OWASP, CWE)
  • Création de règles de détection personnalisées pour votre codebase
  • Analyse du flux de données en mode taint

Installation (CLI)

# pip (recommandé)
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

Scan rapide

semgrep --config auto .                    # Auto-détection des règles

Utilisation d'ensembles de règles

semgrep --config p/<RULESET> .             # Ensemble unique
semgrep --config p/security-audit --config p/trailofbits .  # Multiple
Ensemble de règles Description
p/default Sécurité générale et qualité du code
p/security-audit Règles de sécurité complètes
p/owasp-top-ten Vulnérabilités OWASP Top 10
p/cwe-top-25 Vulnérabilités CWE Top 25
p/trailofbits Règles de sécurité Trail of Bits
p/python Spécifique à Python
p/javascript Spécifique à JavaScript
p/golang Spécifique à Go

Formats de sortie

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

Scanner des chemins spécifiques

semgrep --config p/python app.py           # Fichier unique
semgrep --config p/javascript src/         # Répertoire
semgrep --config auto --include='**/test/**' .  # Inclure les tests

Configuration

.semgrepignore

tests/fixtures/
**/testdata/
generated/
vendor/
node_modules/

Suppression des faux positifs

password = get_from_vault()  # nosemgrep: hardcoded-password
dangerous_but_safe()  # nosemgrep

Part 2: Creating Custom Rules

Quand créer des règles personnalisées

  • Détection de motifs de vulnérabilités spécifiques au projet
  • Application des standards de codage internes
  • Création de vérifications de sécurité pour des frameworks personnalisés
  • Création de règles en mode taint pour l'analyse du flux de données

Sélection de l'approche

Approche À utiliser quand
Mode taint Le flux de données provient d'une source non fiable vers un sink dangereux (vulnérabilités d'injection)
Pattern matching Motifs syntaxiques sans exigences de flux de données (APIs dépréciées, valeurs en dur)

Privilégiez le mode taint pour les vulnérabilités d'injection. Le pattern matching seul ne peut pas faire la différence entre eval(user_input) (vulnérable) et eval("safe_literal") (sûr).

Démarrage rapide : Pattern matching

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

Démarrage rapide : Mode taint

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

Référence rapide de la syntaxe des motifs

Syntaxe Description Exemple
... Correspondre à n'importe quoi func(...)
$VAR Capturer une métavariable $FUNC($INPUT)
<... ...> Correspondance d'expression profonde <... user_input ...>
Opérateur Description
pattern Correspondre au motif exact
patterns Tous doivent correspondre (AND)
pattern-either N'importe lequel correspond (OR)
pattern-not Exclure les correspondances
pattern-inside Correspondre uniquement à l'intérieur du contexte
pattern-not-inside Correspondre uniquement à l'extérieur du contexte
metavariable-regex Regex sur la valeur capturée

Tester les règles

Les tests en premier sont obligatoires. Créez des fichiers de test avec des 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,))

Exécutez les tests :

semgrep --test --config rule.yaml test-file

Référence des commandes

Tâche Commande
Exécuter les tests semgrep --test --config rule.yaml test-file
Valider YAML semgrep --validate --config rule.yaml
Dump AST semgrep --dump-ast -l <lang> <file>
Debug taint flow semgrep --dataflow-traces -f rule.yaml file

Workflow de création de règles

  1. Analyser le problème - Comprendre le motif de bug, déterminer l'approche taint vs pattern
  2. Créer d'abord les cas de test - Écrire les annotations ruleid: et ok: avant la règle
  3. Analyser l'AST - Exécutez semgrep --dump-ast pour comprendre la structure du code
  4. Écrire la règle - Commencez simple, itérez
  5. Tester jusqu'à 100% de succès - Aucune « ligne manquée » ou « ligne incorrecte »
  6. Optimiser les motifs - Supprimez les redondances uniquement après que les tests réussissent

Structure de sortie :

<rule-id>/
├── <rule-id>.yaml     # Règle Semgrep
└── <rule-id>.<ext>    # Fichier de test

Références détaillées

Documentation officielle Semgrep :

  • Rule Syntax - Structure YAML complète, opérateurs et options
  • Rule Schema - Spécification complète du schéma JSON

Références locales :

Anti-motifs à éviter

Trop large :

# MAUVAIS : Correspond à n'importe quel appel de fonction
pattern: $FUNC(...)

# BON : Fonction dangereuse spécifique
pattern: eval(...)

Cas sûrs manquants :

# MAUVAIS : Teste uniquement le cas vulnérable
# ruleid: my-rule
dangerous(user_input)

# BON : Inclure les cas sûrs
# ruleid: my-rule
dangerous(user_input)

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

Rationalisations à rejeter

Raccourci Pourquoi c'est faux
« Semgrep n'a rien trouvé, le code est propre » Semgrep est basé sur des motifs ; ne peut pas suivre le flux de données complexe inter-fonctions
« Le motif semble complet » Les règles non testées ont des faux positifs/négatifs cachés
« Il correspond au cas vulnérable » Correspondre aux vulnérabilités, c'est la moitié du travail ; vérifiez que les cas sûrs ne correspondent pas
« Le mode taint est excessif » Pour les vulnérabilités d'injection, le mode taint offre une meilleure précision
« Un cas de test suffit » Incluez les cas limites : styles de codage différents, entrées assainies, alternatives sûres

Intégration CI/CD

GitHub Actions

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

Ressources

Écriture de règles :

Général :

Skills similaires