Dans l’ère du shift left, attendre le pentest final pour découvrir des failles est une erreur stratégique (et coûteuse). L’analyse statique de sécurité (SAST) détecte les vulnérabilités directement dans le code source, avant compilation ou déploiement - sans accès à un environnement tournant. Le référentiel OWASP SAMM formalise cette pratique dans son domaine Implementation.
La bonne nouvelle : vous n’avez pas besoin d’un budget à six chiffres pour une couverture sérieuse. Voici cinq outils gratuits ou très accessibles, avec leurs commandes concrètes et un exemple de pipeline GitHub Actions complet.
1. Semgrep - SAST multi-langages, règles lisibles
Semgrep s’est imposé comme la référence pour les équipes modernes. Contrairement aux moteurs basés sur les expressions régulières, Semgrep analyse l’AST (arbre syntaxique) du code - les règles ressemblent au code qu’elles cherchent, ce qui rend leur écriture et leur revue accessibles aux développeurs.
- Langages : JavaScript, TypeScript, Python, Go, Java, PHP, Ruby, C/C++, et plus.
- Registre communautaire : des milliers de règles OWASP-aligned disponibles sans configuration.
- Sorties : texte, JSON, SARIF (compatible GitHub Code Scanning).
Installation et premier scan
# Installation via pip (Python 3.9+)
pip install semgrep
# Scan avec les règles de sécurité auto-détectées
semgrep --config auto ./src
# Scan ciblé OWASP Top 10 en JSON (pour CI/CD)
semgrep --config "p/owasp-top-ten" --json -o semgrep-results.json ./src
# Afficher seulement les findings HIGH et ERROR
semgrep --config "p/owasp-top-ten" --severity ERROR --severity WARNING ./src
Exemple de règle personnalisée pour détecter l’usage non sécurisé de eval() en JavaScript :
rules:
- id: no-eval
patterns:
- pattern: eval(...)
message: "Utilisation de eval() détectée - risque d’injection de code."
languages: [javascript, typescript]
severity: ERROR
metadata:
cwe: "CWE-95"
Sortie typique :
src/utils/parser.js
line 42: eval(userInput)
[ERROR] no-eval: Utilisation de eval() détectée - risque d’injection de code.
Ran 312 rules on 48 files: 3 findings.
2. SonarQube Community Edition - qualité + sécurité sur la durée
SonarQube Community offre une plateforme self-hosted avec historique des analyses, Quality Gates configurables et un tableau de bord par projet. C’est l’outil adapté si vous voulez une visibilité sur la dette de sécurité dans le temps, pas seulement sur le dernier commit.
- Points forts : métriques coverage, bugs, code smells, vulnérabilités dans une seule interface.
- Limitation Community : une seule branche analysée (pas de PR analysis nativement - contrairement aux éditions payantes).
Démarrage rapide avec Docker
# Lancer SonarQube en local (persiste les données via volume)
docker run -d --name sonarqube \
-p 9000:9000 \
-v sonarqube_data:/opt/sonarqube/data \
sonarqube:community
# Attendre ~60s, puis accéder à http://localhost:9000
# Identifiants par défaut : admin / admin
# Scanner un projet (depuis la racine du repo)
docker run --rm \
-e SONAR_HOST_URL="http://host.docker.internal:9000" \
-e SONAR_TOKEN="votre_token_ici" \
-v "$(pwd):/usr/src" \
sonarsource/sonar-scanner-cli \
-Dsonar.projectKey=mon-projet \
-Dsonar.sources=src
Le Quality Gate par défaut bloque si le taux de nouvelles vulnérabilités dépasse 0 - ce qui en fait un frein naturel aux régressions.
3. Bandit - SAST ciblé Python
Bandit est l’outil de référence pour l’analyse statique de sécurité Python. Il parcourt les fichiers source en s’appuyant sur l’AST et signale des patterns dangereux : désérialisation pickle, chargement YAML sans safe_load, appels subprocess avec shell=True, hachage MD5, etc.
Installation et usage
pip install bandit
# Scan récursif avec rapport texte
bandit -r ./app
# Rapport JSON pour CI/CD, seulement HIGH
bandit -r ./app -ll -f json -o bandit-report.json
# Exclure les faux positifs connus
bandit -r ./app --skip B101,B601
Exemple de finding typique :
Issue: [B506:yaml_load] Use of unsafe yaml.load detected.
Severity: Medium Confidence: High
Location: app/config.py line 18
17: with open(config_path) as f:
18: config = yaml.load(f) # ← devrait être yaml.safe_load(f)
Run metrics:
Total issues: 4 (High: 1, Medium: 2, Low: 1)
Files skipped: 0
Correction immédiate :
# Avant (dangereux - exécution de code arbitraire possible)
config = yaml.load(f)
# Après (sûr)
config = yaml.safe_load(f)
4. Gitleaks - détection de secrets dans l’historique Git
Gitleaks n’est pas un SAST traditionnel : il scanne l’historique complet Git (commits, branches, stash) pour détecter des secrets qui n’auraient pas dû être commités - clés AWS, tokens GitHub, clés privées RSA, mots de passe en dur, etc. Un secret dans Git reste exposé même après suppression du fichier si l’historique n’est pas réécrit.
Installation et usage
# Installation (Linux/macOS)
curl -sSfL https://github.com/gitleaks/gitleaks/releases/latest/download/gitleaks_linux_x64.tar.gz | tar -xz
sudo mv gitleaks /usr/local/bin/
# Scan de tout l’historique du dépôt courant
gitleaks detect --source . --report-format json --report-path gitleaks-report.json
# Mode pre-commit : seulement les fichiers stagés
gitleaks protect --staged
# Scan d’un commit ou d’une plage
gitleaks detect --log-opts="HEAD~5..HEAD"
Exemple de finding :
Finding:
Description: AWS Access Key
File: config/settings.py
Line: 14
Secret: AKIAIOSFODNN7EXAMPLE
Commit: a3f2b1c
Author: dev@example.com
Date: 2025-11-03T10:22:18Z
En cas de secret détecté : révoquer immédiatement la clé dans la console AWS/GitHub/etc., puis réécrire l’historique avec git filter-repo ou BFG Repo-Cleaner. Ne jamais supposer que personne n’a vu un secret dans un dépôt public - les crawlers passent en quelques minutes.
Intégration pre-commit (recommandé)
# .pre-commit-config.yaml
repos:
- repo: https://github.com/gitleaks/gitleaks
rev: v8.21.2
hooks:
- id: gitleaks
# Activer les pre-commit hooks
pip install pre-commit
pre-commit install
5. Snyk (offre Free) - SCA et SAST dans le cloud
Snyk est une plateforme commerciale avec une offre gratuite couvrant jusqu’à 200 tests/mois pour les projets open source. Sa force est le SCA (Software Composition Analysis) : il analyse vos dépendances (package.json, requirements.txt, pom.xml, etc.) et les croise avec sa base de CVE pour identifier celles qui sont vulnérables - avec un chemin de remédiation suggéré.
- SCA : Node.js, Python, Java, Go, .NET, PHP, Ruby.
- SAST (Snyk Code) : disponible en free avec des limites mensuelles.
- Infrastructure as Code : analyse Terraform, CloudFormation, Helm.
# Installation
npm install -g snyk
# Authentification (crée un compte gratuit)
snyk auth
# Scanner les dépendances du projet courant
snyk test
# Scanner le code source (SAST)
snyk code test ./src
# Monitorer en continu (dashboard Snyk)
snyk monitor
Exemple de sortie snyk test :
✗ High severity vulnerability found in lodash
Description: Prototype Pollution
Info: https://security.snyk.io/vuln/SNYK-JS-LODASH-1040724
Introduced through: express@4.17.1 › lodash@4.17.20
Fix: upgrade lodash to 4.17.21
✗ Medium severity vulnerability found in axios
Description: SSRF (Server Side Request Forgery)
Introduced through: axios@0.21.1
Fix: upgrade axios to 0.21.2
Tested 247 dependencies for known issues, found 3 issues.
6. Comparatif détaillé
| Outil | Type | Langages / cible | Faux positifs | Intégration CI/CD | Gratuit ? |
|---|---|---|---|---|---|
| Semgrep | SAST | Multi (20+) | Faible (AST-based) | JSON, SARIF, GitHub Actions, GitLab CI | Oui (OSS) |
| SonarQube | SAST + qualité | Multi (30+) | Moyen | Self-hosted, scanner Docker | Community edition |
| Bandit | SAST | Python uniquement | Faible à moyen | CLI, pip, JSON output | Oui (OSS) |
| Gitleaks | Secret scanning | Tous dépôts Git | Très faible | Pre-commit, pipeline, Docker | Oui (OSS) |
| Snyk | SCA + SAST | Multi (Node, Python, Java…) | Faible (CVE-based) | Cloud + CLI + GitHub App | 200 tests/mois |
7. Pipeline GitHub Actions complet
Voici un workflow combinant Gitleaks (pre-push), Semgrep (SAST) et Snyk (SCA) sur chaque Pull Request, avec fail-fast sur les findings HIGH/CRITICAL :
# .github/workflows/security.yml
name: Security Scan
on:
push:
branches: [main, develop]
pull_request:
branches: [main]
jobs:
# 1. Détection de secrets dans l’historique Git
gitleaks:
name: Secret Scanning (Gitleaks)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0 # historique complet requis
- name: Run Gitleaks
uses: gitleaks/gitleaks-action@v2
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# 2. Analyse statique (SAST)
semgrep:
name: SAST (Semgrep)
runs-on: ubuntu-latest
container:
image: semgrep/semgrep
steps:
- uses: actions/checkout@v4
- name: Run Semgrep
run: |
semgrep \
--config "p/owasp-top-ten" \
--config "p/secrets" \
--sarif \
--output semgrep.sarif \
--error \
./src
- name: Upload SARIF to GitHub
if: always()
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: semgrep.sarif
# 3. Analyse des dépendances (SCA)
snyk:
name: SCA (Snyk)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Run Snyk
uses: snyk/actions/node@master
env:
SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
with:
args: --severity-threshold=high --fail-on=all
Points clés du pipeline :
fetch-depth: 0est indispensable pour que Gitleaks scanne tout l’historique, pas uniquement le dernier commit.--sarif+upload-sarifaffiche les findings directement dans l’onglet Security de la PR, sans naviguer dans les logs.--error(Semgrep) et--fail-on=all(Snyk) font échouer le job sur n’importe quel finding - adapter selon votre politique (--severity-threshold=highpour ne bloquer que sur HIGH+).
8. Stratégie de déploiement progressif
Brancher tous ces outils le premier jour sur un projet existant génère souvent des dizaines de findings qui noient les équipes et démotivent rapidement. Une approche en trois phases :
- Semaine 1 - audit : lancer les outils en mode reporting only (sans
--error), recenser les findings existants, identifier les faux positifs évidents. Créer un fichier.semgrepignore/.banditignorepour les exclure. - Semaine 2-4 - fail-fast sur le nouveau code : activer le code de sortie non nul uniquement sur les fichiers modifiés dans la PR (option
--diffdans Semgrep,--log-opts="origin/main..HEAD"dans Gitleaks). La dette existante n’est pas bloquante, le nouveau code l’est. - Mois 2+ - remédiation de la dette : résoudre les findings par criticité (CRITICAL → HIGH → MEDIUM), mettre à jour les baselines au fur et à mesure.
Conseil : définir dans le Quality Gate ou dans la CI le seuil acceptable - par exemple, zéro finding CRITICAL autorisé en production, les MEDIUM remontés en ticket Jira/Linear sans bloquer.
9. Les limites à connaître
Ces outils couvrent ce qui est détectable statiquement. Ils ne remplacent pas l’analyse dynamique ni le test manuel pour :
- IDOR et contrôle d’accès métier : le SAST ne connaît pas vos rôles utilisateurs ni votre logique d’autorisation.
- Race conditions et vulnérabilités de timing : invisibles à l’analyse statique.
- Contournements de workflow : un attaquant qui enchaîne des appels API dans un ordre inattendu - seul un test manuel ou un pentest web le détecte.
- Abus de configuration cloud : les IAM trop permissifs ou les buckets S3 mal configurés nécessitent des outils dédiés (Prowler, ScoutSuite) - voir l’article sur les erreurs IAM critiques AWS.
Le SAST est une première ligne efficace - pas une garantie d’absence de vulnérabilités.
Conclusion
Sécuriser le code n’est plus une question de budget, mais de méthode : Gitleaks sur le pre-commit, Semgrep sur chaque PR, Snyk sur les dépendances - et un pipeline qui fait échouer le build sur les findings critiques. En quelques heures de configuration, vous éliminez une grande partie des défauts évidents avant la production.
Pour valider ce qui reste - les vulnérabilités logiques, les mauvaises configurations cloud, les abus de session - un pentest manuel est l’étape suivante : parlons de votre contexte.