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
- Analyser le problème - Comprendre le motif de bug, déterminer l'approche taint vs pattern
- Créer d'abord les cas de test - Écrire les annotations
ruleid:etok:avant la règle - Analyser l'AST - Exécutez
semgrep --dump-astpour comprendre la structure du code - Écrire la règle - Commencez simple, itérez
- Tester jusqu'à 100% de succès - Aucune « ligne manquée » ou « ligne incorrecte »
- 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 :
- Workflow Guide - Processus complet de création de règles étape par étape
- Quick Reference - Opérateurs de motifs et composants taint
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 :
- 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
Général :
- 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