Semgrep est un outil de SAST (Static Application Security Testing) open source créé par la société r2c (acquise par GitLab en 2024), devenu en 2026 le standard de facto pour le scan de code source en contexte DevSecOps. Il combine rapidité (scan projet 100 kLoC en 1-3 minutes), syntaxe YAML déclarative accessible en 2-4 heures d'apprentissage, couverture multi-langages (30+ langages dont Python, JavaScript, TypeScript, Java, Go, Rust, C, C++, Ruby, PHP, Kotlin, Swift) et registry public de 2500+ règles communautaires (p/owasp-top-ten, p/cwe-top-25, p/secrets, p/jwt). Sa licence LGPL permet un usage production sans coût. Semgrep sert à 4 cas d'usage principaux : scan SAST dans le pipeline CI/CD, écriture de règles custom pour enforce des patterns internes, scan pre-commit et IDE en feedback immédiat, audit manuel d'un codebase via ligne de commande. Il se distingue de CodeQL (plus profond sémantiquement mais plus lent et complexe) et de SonarQube (orienté qualité plus sécurité basique) par son sweet spot rapidité / simplicité / customisation. Versions commerciales Semgrep Pro (environ 40 $/dev/mois) et AppSec Platform (enterprise) ajoutent taint inter-procédural et dashboard centralisé. Cet article détaille la définition, le fonctionnement technique, la syntaxe des règles, les cas d'usage concrets, la comparaison avec CodeQL, SonarQube, Snyk Code, Checkmarx et Veracode, l'intégration CI/CD, le tuning et les limites. Sources : docs officielles Semgrep, OWASP Benchmark Project 2024, GitLab acquisition announcement.
1. Définition et positionnement
Semgrep (contraction de « semantic grep ») est un outil de recherche de motifs sémantiques dans le code source, évolué vers le SAST. Sa particularité : écrire un pattern dans la syntaxe du langage cible, pas une regex ni un AST descriptor.
Exemple conceptuel : pour détecter eval(user_input) en Python, on écrit pattern: eval($INPUT) avec $INPUT comme métavariable. Semgrep parse le code en AST, cherche tous les nœuds qui matchent cette forme, indépendamment du nom de la variable ou des espaces.
1.1 Histoire rapide
- 2017-2019 : projet semgrep chez Facebook (ancêtre
pfffde Yoann Padioleau). - 2020 : fondation r2c, open-sourcing, levée de fonds.
- 2022-2023 : croissance rapide de l'adoption communautaire, dépassement de Bandit et Brakeman dans les benchmarks.
- Mars 2024 : acquisition par GitLab pour intégrer Semgrep dans GitLab Ultimate SAST.
- 2024-2026 : développement continu en mode dual OSS / Pro, maintien LGPL pour le core.
1.2 Positionnement marché 2026
| Position | Semgrep | CodeQL | SonarQube | Snyk Code |
|---|---|---|---|---|
| Licence core | LGPL (OSS) | MIT (gratuit pour repos publics) | LGPL (Community) | Propriétaire |
| Rapidité | Très rapide (1-3 min) | Lent (30-60 min) | Moyen (5-15 min) | Rapide (2-5 min) |
| Profondeur sémantique | Moyenne (Pro meilleure) | Très profonde | Moyenne | Profonde (ML) |
| Customisation règles | Très facile (YAML 2-4 h) | Complexe (QL 20-40 h) | Moyenne (Java) | Faible |
| Intégration CI native | Excellente | Excellente (GitHub) | Bonne | Bonne |
| Adoption France 2026 | Très forte | Forte (repos publics) | Très forte (legacy qualité) | Croissante |
Semgrep occupe le sweet spot pour démarrer un programme SAST : rapide à installer, facile à customiser, couvre les 30-50 % de vulnérabilités que tout SAST peut détecter selon OWASP Benchmark Project 2024.
2. Comment ça marche : les 3 modes d'analyse
Semgrep opère selon trois modes de complexité croissante.
2.1 Mode syntaxique (pattern matching AST)
Le mode de base. L'outil parse le code en AST, cherche des patterns littéraux ou métavariables.
rules:
- id: python-no-eval
pattern: eval($INPUT)
message: "Usage de eval détecté. Utiliser ast.literal_eval pour parser du JSON."
languages: [python]
severity: ERROR
metadata:
cwe: "CWE-95"
owasp: "A03:2021-Injection"Forces : rapide, précis, facile à écrire. Limites : ne suit pas le flow de données à travers fonctions.
2.2 Mode taint (source-to-sink analysis)
Trace le flux des données non fiables (sources) vers les fonctions dangereuses (sinks), signale les chemins non sanitizés.
rules:
- id: nodejs-sql-injection-taint
mode: taint
pattern-sources:
- pattern-either:
- pattern: $REQ.body.$FIELD
- pattern: $REQ.query.$FIELD
- pattern: $REQ.params.$FIELD
pattern-sinks:
- pattern-either:
- pattern: $DB.query($X, ...)
- pattern: $DB.raw($X)
pattern-sanitizers:
- pattern: mysql.escape(...)
- pattern: sqlstring.escape(...)
message: "Tainted flow from HTTP input to SQL query sans sanitization"
languages: [javascript, typescript]
severity: ERROR
metadata:
cwe: "CWE-89"
owasp: "A03:2021-Injection"Forces : détecte des vulnérabilités inter-instructions. Limites : le mode OSS est intra-function ; le mode Pro étend l'analyse inter-procédurale (source dans fonction A, sink dans fonction B).
2.3 Mode semantic dataflow (Semgrep Pro)
Analyse sémantique avancée avec dataflow inter-module, type inference, tracking de variables renommées. Disponible uniquement en version Pro.
Forces : détection de 20-30 % de vrais positifs additionnels vs OSS selon benchmarks internes GitLab 2024. Limites : plus lent, payant, complexité de tuning accrue.
3. Anatomie d'une règle Semgrep
Structure générale d'un fichier de règles en YAML.
rules:
- id: <identifiant-unique-kebab-case>
patterns: # OU pattern, OU pattern-either, OU pattern-not
- pattern: <code-pattern-dans-le-langage-cible>
- pattern-not: <exclusion-pattern>
metavariable-pattern:
metavariable: $VAR
pattern: <sous-pattern-sur-la-métavariable>
message: |
Message multi-lignes expliquant la vulnérabilité, l'impact,
et la contre-mesure recommandée.
severity: ERROR # INFO, WARNING, ERROR
languages: [python, javascript, typescript]
metadata:
cwe: "CWE-89"
owasp: "A03:2021-Injection"
confidence: HIGH
category: security
technology: [express, django]
references:
- "https://owasp.org/www-community/attacks/SQL_Injection"
fix: <suggestion-de-remplacement-si-possible>3.1 Les champs clés
- id : identifiant unique en kebab-case, sert à ignorer sélectivement la règle.
- pattern / patterns : le cœur de la règle, syntaxe du langage cible avec métavariables.
- pattern-either : OR logique entre patterns.
- pattern-not : exclusion, pour autoriser certains cas.
- patterns (pluriel) : AND logique, tous les sous-patterns doivent matcher.
- metavariable-pattern : contraintes sur une métavariable (ex: uniquement si c'est une string literal).
- message : explication lue par le dev et l'équipe AppSec.
- severity : INFO (log), WARNING (non-bloquant), ERROR (bloquant CI).
- languages : liste des langages ciblés.
- metadata : mapping CWE/OWASP, confidence, références.
- fix : suggestion d'autoremediation (Semgrep peut proposer un replace automatique).
3.2 Les métavariables ($VAR, $..., $...ARG)
$VAR: capture un identifiant (variable, fonction, classe).$...: wildcard de longueur variable dans les arguments.$...ARG: capture une séquence nommée d'arguments....(dans le pattern) : wildcard générique pour "n'importe quoi".
Exemple : pattern: $FUNC(...) matche tout appel de fonction quel que soit le nombre d'arguments.
3.3 Tester ses règles
Semgrep supporte des tests unitaires de règles via annotations dans les fichiers de test.
# tests/python-no-eval.py
import ast
# ruleid: python-no-eval
eval("print('hello')")
# ok: python-no-eval
ast.literal_eval("{'key': 'value'}")
# ruleid: python-no-eval
user_input = input("Enter: ")
result = eval(user_input)Commande de test : semgrep --test .semgrep/rules/python-no-eval.yaml --test-tests tests/. Les annotations ruleid: marquent les lignes qui doivent matcher, les annotations ok: marquent celles qui ne doivent pas matcher.
4. Le Semgrep Registry : 2500+ règles prêtes à l'emploi
Le registry public est l'avantage concurrentiel majeur 2026. Catalogue curé maintenu par r2c/GitLab et la communauté.
4.1 Packs de règles clés
| Pack | Nombre de règles | Couverture |
|---|---|---|
p/default | ~300 | Base raisonnable multi-langage |
p/owasp-top-ten | ~400 | OWASP Top 10 2021 par langage |
p/cwe-top-25 | ~350 | CWE Top 25 SANS/MITRE 2024 |
p/secrets | ~150 | AWS keys, GCP tokens, private keys, etc. |
p/jwt | ~40 | Implémentations JWT non sécurisées |
p/command-injection | ~120 | Injection de commandes OS |
p/sql-injection | ~180 | SQL injection par ORM/langage |
p/xss | ~200 | XSS reflected, stored, DOM |
p/docker | ~60 | Dockerfile best practices et sécurité |
p/ci | ~80 | Workflow GitHub Actions, GitLab CI vulns |
p/terraform | ~250 | IaC Terraform misconfigurations |
4.2 Comment choisir les packs
- Équipe qui démarre :
p/default+p/secrets. Ratio signal/bruit bon, apprentissage progressif. - Équipe mature :
p/owasp-top-ten+p/cwe-top-25+p/secrets+ custom rules. - Stack spécifique : ajouter les packs par techno (
p/django,p/express,p/react,p/flask,p/laravel). - Équipe DevSecOps : intégrer
p/cietp/dockerpour sécuriser le pipeline lui-même (cf. CI/CD sécurisée : définition).
4.3 Contribuer au registry
Le registry est public, les PRs communautaires sont acceptées sur semgrep.dev/r. Une règle bien écrite avec tests est mergée typiquement en 2-4 semaines. Contribution open source rapide à monter au CV d'un DevSecOps junior.
5. Cas d'usage concrets en 2026
5.1 SAST en pipeline CI/CD (cas le plus courant)
Scan sur chaque pull request, seuil bloquant sur severity ERROR.
# .github/workflows/semgrep.yml
name: semgrep
on:
pull_request:
branches: [main]
push:
branches: [main]
permissions:
contents: read
security-events: write
jobs:
semgrep:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: returntocorp/semgrep-action@v1
with:
config: >-
p/owasp-top-ten
p/cwe-top-25
p/secrets
.semgrep/rules/
generateSarif: "1"
- uses: github/codeql-action/upload-sarif@v3
if: always()
with:
sarif_file: semgrep.sarif5.2 Scan local ligne de commande (audit manuel, code review)
# Scan rapide avec un pack de règles
semgrep --config p/owasp-top-ten .
# Scan avec règles custom locales
semgrep --config .semgrep/rules/ src/
# Scan avec output SARIF
semgrep --config p/cwe-top-25 --sarif -o results.sarif .
# Scan en mode diff (uniquement fichiers modifiés par rapport à main)
semgrep --config p/default --baseline-commit=main5.3 Plugin IDE (VS Code, JetBrains, Vim)
Extension officielle Semgrep disponible pour VS Code (Marketplace) et JetBrains. Feedback en temps réel pendant l'édition, mise en évidence inline des findings avec explication au survol.
Avantages : les devs voient le problème avant même de commiter, l'apprentissage est naturel par itération.
5.4 Pre-commit hook (git)
# .pre-commit-config.yaml
repos:
- repo: https://github.com/returntocorp/semgrep
rev: v1.75.0
hooks:
- id: semgrep
args:
- --config=.semgrep/rules/pre-commit.yaml
- --error
- --quietPattern recommandé : un subset rapide de règles (moins de 30 secondes) en pre-commit (typiquement secrets et patterns custom interne), le scan complet en CI.
5.5 Audit manuel de codebase acquis ou M&A
Scénario : une organisation rachète une société, audit du code avant intégration. Semgrep permet en quelques heures de cartographier la dette sécurité d'un codebase legacy de plusieurs millions de lignes.
# Audit global avec packs complets
semgrep --config p/owasp-top-ten --config p/cwe-top-25 --config p/secrets \
--json --output=audit.json .
# Analyse statistique des résultats
jq '.results | group_by(.check_id) | map({rule: .[0].check_id, count: length}) | sort_by(-.count)' audit.json5.6 Security champion program et dette technique
Les security champions (devs désignés dans chaque équipe pour porter la sécurité, cf. Pourquoi apprendre le secure coding) utilisent Semgrep comme outil de sensibilisation : scans mensuels sur leur repo, discussion des findings en équipe, écriture progressive de règles customs pour enforcer les bonnes pratiques de l'équipe.
6. Semgrep vs alternatives : analyse détaillée
Comparatif technique fondé sur OWASP Benchmark Project 2024 et retours terrain France 2024-2026.
6.1 Semgrep vs CodeQL
| Dimension | Semgrep | CodeQL |
|---|---|---|
| Profondeur sémantique | Moyenne (OSS), Haute (Pro) | Très haute (native) |
| Vitesse | 1-3 min | 30-60 min |
| Complexité règles custom | Faible (YAML 2-4 h) | Haute (QL, 20-40 h) |
| Langages | 30+ | 12 majeurs |
| Licence | LGPL (OSS) | MIT (gratuit repos publics) |
| Intégration CI | Excellente | Excellente (GitHub Actions) |
| Détection zero-day cross-function | Limitée OSS, OK Pro | Excellente |
| Usage typique 2026 | Tout projet, pipeline CI | Repos publics ou nightly |
Complémentarité : Semgrep sur chaque PR pour feedback rapide, CodeQL en nightly pour analyse profonde. Les deux ingestés en SARIF dans GitHub Security.
6.2 Semgrep vs SonarQube
| Dimension | Semgrep | SonarQube |
|---|---|---|
| Focus | Sécurité orientée rules | Qualité + sécurité basique |
| Dashboard UI | Semgrep AppSec Platform (payant) | SonarQube intégré OSS |
| Langages | 30+ | 30+ |
| Faux positifs | 15-30 % (OSS default) | 25-40 % (Developer) |
| Intégration PR review | Excellente (SARIF natif) | Bonne (commentaires PR) |
| Customisation règles | Très facile | Moyenne (plugins Java) |
| Dette technique legacy | Géré via baseline | Géré via quality gates |
Pattern hybride : SonarQube pour qualité code globale (coverage, duplications, code smells), Semgrep pour sécurité pure. Les deux coexistent souvent.
6.3 Semgrep vs Snyk Code
| Dimension | Semgrep | Snyk Code |
|---|---|---|
| Licence | LGPL (OSS) | Propriétaire |
| Prix | Gratuit OSS, Pro 40 $/dev/mois | 60-100 $/user/mois |
| Technologie | Pattern matching + taint | ML-based (DeepCode) |
| Faux positifs | 15-30 % OSS | 10-25 % (ML ranking) |
| Registry public | 2500+ règles | Rules propriétaires |
| Écosystème | Intégration DevSecOps généraliste | Intégration Snyk suite (SCA, IaC, Container) |
Recommandation 2026 : Semgrep OSS ou Pro pour une équipe qui veut contrôle et coût maîtrisé, Snyk Code pour une organisation qui adopte la suite Snyk complète.
6.4 Semgrep vs Checkmarx et Veracode
Les outils enterprise historiques (Checkmarx SAST, Veracode, Fortify) conservent leur place dans les banques, OIV et grands groupes pour des raisons de reporting audit, de SLA contractuel et de traçabilité compliance. Leur inconvénient : prix 80-300 k€/an, faux positifs 30-50 % en baseline, tuning lourd.
Semgrep Pro ou AppSec Platform est devenu en 2024-2026 une alternative crédible dans ces contextes, à prix inférieur et customisation supérieure, mais l'inertie enterprise rend le basculement progressif.
7. Intégration CI/CD avancée
7.1 Seuils et politiques
# Configuration Semgrep CI avec policies différenciées
name: semgrep
on:
pull_request:
push:
branches: [main]
jobs:
semgrep:
runs-on: ubuntu-latest
container:
image: returntocorp/semgrep:latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0 # pour baseline-commit
- name: Semgrep scan (bloquant sur nouvelles vulns)
run: |
semgrep ci \
--config=p/owasp-top-ten \
--config=p/cwe-top-25 \
--config=p/secrets \
--config=.semgrep/rules/ \
--baseline-commit=origin/main \
--error
- name: Semgrep scan full (warning only sur dette)
continue-on-error: true
run: |
semgrep \
--config=p/owasp-top-ten \
--sarif \
--output=semgrep-full.sarif \
.
- uses: github/codeql-action/upload-sarif@v3
if: always()
with:
sarif_file: semgrep-full.sarifLogique de cette configuration : la dette existante (baseline) n'est pas bloquante, seules les nouvelles vulnérabilités introduites par la PR le sont. Les findings complets sont toujours reportés pour tracking.
7.2 Ingestion SARIF et reporting centralisé
- GitHub Security tab : ingest SARIF via
github/codeql-action/upload-sarif, déduplication automatique. - GitLab Security Dashboard : ingest natif dans GitLab Ultimate.
- DefectDojo (OWASP) : agrégateur multi-scanners open source.
- Semgrep AppSec Platform (Pro enterprise) : dashboard natif cross-projets.
7.3 Pattern pour monorepo
# Scan sélectif d'un monorepo
jobs:
semgrep-backend:
if: contains(github.event.pull_request.labels.*.name, 'backend')
runs-on: ubuntu-latest
steps:
- uses: returntocorp/semgrep-action@v1
with:
config: p/python p/django
publishToken: $${{ secrets.SEMGREP_APP_TOKEN }}
semgrep-frontend:
if: contains(github.event.pull_request.labels.*.name, 'frontend')
runs-on: ubuntu-latest
steps:
- uses: returntocorp/semgrep-action@v1
with:
config: p/javascript p/react p/nextjs8. Tuning et gestion des faux positifs
8.1 Mesure initiale du taux de faux positifs
Chiffres typiques après scan initial d'un projet mature :
- Scan OSS
p/defaultseul : 10-20 % FP. - Scan OSS
p/owasp-top-ten+p/cwe-top-25: 20-35 % FP. - Scan Pro avec taint mode inter-procédural : 10-20 % FP.
8.2 Stratégies de réduction
- Ignorer une règle globalement non pertinente (ex: pas de crypto dans l'app)
# .semgrepignore
rules:
- id: generic.secrets.security.detected-aws-access-key
paths:
exclude:
- "tests/fixtures/**" # faux positifs sur fixtures de tests- Annotation inline justifiée
# nosemgrep: python.lang.security.audit.dangerous-exec.dangerous-exec
# Reason: input already sanitized via sanitize_code() at function entry
exec(sanitized_code)- Custom rule plus précise remplaçant règle générique
Si une règle générique produit 80 % de FP, écrire une règle custom qui matche uniquement les vrais cas. Documentée et testée.
- Monitoring du taux d'ignore par équipe
KPI à suivre : taux de nosemgrep par équipe. Si supérieur à 20 %, challenge en retro AppSec.
9. Limites structurelles de Semgrep
Honnêteté sur ce que Semgrep ne fait pas.
- Business logic invisible : IDOR, broken access control niveau ressource, workflow métier contournable. Semgrep ne comprend pas la sémantique métier.
- Vulnérabilités runtime : variables d'environnement, headers HTTP, config cloud, CORS dynamique. Non-détectable statique.
- Zero-day avant règle publiée : règle doit exister dans registry ou être écrite en interne.
- Taint inter-procédural en OSS : limité à intra-function, besoin de Pro pour dataflow cross-module.
- Dépendances tierces non-scannées : Semgrep scanne le code custom, pas les libs. SCA (Trivy, Snyk, OSV-scanner) reste obligatoire.
- Règles custom mal écrites : peuvent produire beaucoup de FP, revue AppSec obligatoire.
Corollaire : Semgrep est un outil indispensable mais non suffisant. La stack DevSecOps 2026 comprend au minimum Semgrep + SCA + secrets scanning + IaC scanning + DAST nightly. Voir CI/CD sécurisée : définition pour la stack complète.
10. Roadmap d'adoption Semgrep en 3 phases
| Phase | Durée | Actions | Couverture |
|---|---|---|---|
| Phase 1 Discovery | M0-M1 | CLI local, p/default, mesure baseline FP | Exploration |
| Phase 2 CI intégration | M1-M3 | Pipeline PR + main, p/owasp-top-ten, seuil bloquant new findings | Production basique |
| Phase 3 Customisation | M3-M9 | Règles custom stack interne, taint mode, Pre-commit hooks, IDE plugins | Mature |
| Phase 4 Scale | M9-M18 | Security champions formés, règles contribuées au registry, Pro si besoin | Enterprise |
Points clés à retenir
- Semgrep = SAST open-source multi-langage (30+), syntaxe YAML déclarative accessible en 2-4 h d'apprentissage, scan 100 kLoC en 1-3 min.
- Licence LGPL OSS gratuite suffit pour la majorité des cas. Pro à 40 $/dev/mois ajoute taint inter-procédural et dashboard centralisé.
- 3 modes d'analyse : syntaxique (AST matching), taint (source-to-sink intra OSS, inter-procédural Pro), semantic dataflow (Pro).
- Registry public 2500+ règles :
p/owasp-top-ten,p/cwe-top-25,p/secrets,p/jwt,p/ci,p/docker,p/terraformet plus. - 6 cas d'usage : CI/CD pipeline, CLI audit manuel, plugin IDE, pre-commit hook, audit M&A, security champion program.
- Comparaison : complémentaire de CodeQL (plus profond, plus lent), alternative à SonarQube focus sécurité, concurrent de Snyk Code (ML-based payant).
- Stratégie baseline : ne bloquer que les new findings introduits par PR, traiter la dette legacy progressivement.
- Stack DevSecOps 2026 complète : Semgrep (SAST) + Trivy (SCA et container) + gitleaks (secrets) + Checkov (IaC) + ZAP ou Burp (DAST) + Cosign (signing).
- Roadmap d'adoption : CLI local → CI intégration → règles custom → security champions scale, 9-18 mois selon maturité.
Pour aller plus loin
- Qu'est-ce qu'un SAST — concept SAST et comparaison exhaustive outils.
- SAST vs DAST — complémentarité des paradigmes de scan.
- CI/CD sécurisée : définition — positionnement de Semgrep dans le pipeline sécurisé.
- Roadmap DevSecOps — skill tree DevSecOps incluant Semgrep niveau 4.
- Devenir DevSecOps sans expérience — pillar DevSecOps.







