Aller au contenu

SAST : analyser le code source pour détecter les failles

Mise à jour :

En 2017, Equifax subit une fuite massive : 147 millions de dossiers exposés. La cause ? Une vulnérabilité Apache Struts non corrigée. Mais le problème remontait plus loin : le code de l’application contenait des failles d’injection qui auraient pu être détectées par une analyse statique bien avant le déploiement.

Le SAST (Static Application Security Testing) permet de détecter ces failles avant qu’elles n’atteignent la production. C’est l’approche “shift-left” par excellence : trouver les problèmes au moment où ils coûtent le moins cher à corriger.

Qu’est-ce que le SAST ?

Le SAST (Static Application Security Testing) analyse le code source d’une application pour y détecter des vulnérabilités, sans jamais l’exécuter. L’outil parcourt le code, suit les flux de données et identifie les patterns problématiques.

Concrètement, le SAST répond à la question : “Mon code contient-il des failles de sécurité connues ?”

Comment fonctionne un scanner SAST

Un outil SAST procède en plusieurs étapes :

  1. Parsing du code source

    Le scanner convertit le code en une représentation structurée (AST, Abstract Syntax Tree). Cette étape lui permet de comprendre la syntaxe du langage.

  2. Analyse du flux de données

    L’outil suit le parcours des données dans le code : d’où viennent-elles (sources) et où vont-elles (sinks). Une donnée utilisateur qui atteint une requête SQL sans validation est suspecte.

  3. Matching de patterns

    Le scanner compare le code à une base de règles qui décrivent des vulnérabilités connues. Exemple : “une concaténation de string dans une requête SQL” → risque d’injection.

  4. Génération du rapport

    L’outil produit une liste de findings avec le fichier, la ligne, la description de la faille et souvent une suggestion de correction.

Ce que le SAST détecte

Le SAST couvre un large spectre de vulnérabilités :

CatégorieExemplesImpact
InjectionsSQL, XSS, Command, LDAPExécution de code, vol de données
AuthentificationComparaison timing-unsafe, bypassUsurpation d’identité
CryptographieAlgorithmes faibles, IV prévisiblesDonnées déchiffrables
Secrets hardcodésMots de passe, tokens, clés APIAccès non autorisé
Contrôle d’accèsVérifications manquantesÉlévation de privilèges
Gestion d’erreursStack traces exposéesFuite d’informations

SAST vs DAST : quelle différence ?

AspectSASTDAST
QuandPendant le développementAprès déploiement
CommentAnalyse le code sourceTeste l’application en cours d’exécution
CouvertureTout le code, même non exécutéSeulement les chemins testés
Faux positifsPlus nombreuxMoins nombreux
Contexte runtimeNonOui
VitesseRapide à modéréPlus lent

Les deux approches sont complémentaires. Le SAST trouve des failles que le DAST ne verra jamais (code mort, chemins rares), et inversement.

Les trois domaines du SAST

Le terme SAST recouvre en réalité trois types d’analyse distincts :

1. Analyse du code applicatif

C’est le SAST “classique” : scanner le code métier (Java, Python, JavaScript, Go…) pour y trouver des vulnérabilités.

Outils recommandés :

OutilLangagesPoints forts
Semgrep30+Règles personnalisables, rapide, gratuit
CodeQLJava, JS, Python, Go, C++Requêtes puissantes, intégré GitHub
BanditPythonSimple, spécialisé Python
SonarQube25+Qualité + sécurité, dashboard

Exemple avec Semgrep :

Terminal window
# Scanner avec les règles de sécurité OWASP
semgrep --config=p/owasp-top-ten .
# Scanner avec toutes les règles de sécurité
semgrep --config=p/security-audit .

Semgrep détecte par exemple une injection SQL :

# ❌ Vulnérable - concaténation directe
query = "SELECT * FROM users WHERE id = " + user_id
cursor.execute(query)
# ✅ Sécurisé - requête paramétrée
query = "SELECT * FROM users WHERE id = %s"
cursor.execute(query, (user_id,))

2. Analyse de l’Infrastructure as Code (IaC)

Les fichiers Terraform, Kubernetes, Dockerfile contiennent aussi des failles : ports exposés, privilèges excessifs, secrets en clair.

Outils recommandés :

OutilCiblesPoints forts
CheckovTerraform, K8s, Dockerfile, ARM1000+ règles, policies as code
DockleImages DockerBest practices CIS
KICSMulti-IaCLarge couverture
tfsecTerraformSpécialisé, précis

Exemple avec Checkov :

Terminal window
# Scanner un répertoire Terraform
checkov -d ./terraform/
# Scanner un Dockerfile
checkov -f Dockerfile

Checkov détecte par exemple un conteneur qui tourne en root :

# ❌ Vulnérable - pas de contexte de sécurité
apiVersion: v1
kind: Pod
spec:
containers:
- name: app
image: mon-app:latest
# ✅ Sécurisé - utilisateur non-root
apiVersion: v1
kind: Pod
spec:
securityContext:
runAsNonRoot: true
runAsUser: 1000
containers:
- name: app
image: mon-app:latest

Guide Checkov | Guide Dockle

3. Détection de secrets

Les secrets hardcodés (mots de passe, tokens, clés API) sont une catégorie critique. Des outils spécialisés scannent le code et l’historique Git.

Outils recommandés :

OutilPoints forts
GitleaksRapide, règles complètes, pre-commit
TruffleHogDétection entropie, vérification live
detect-secretsBaseline pour réduire le bruit

Exemple avec Gitleaks :

Terminal window
# Scanner le répertoire courant
gitleaks detect --source . -v
# Scanner tout l'historique Git
gitleaks detect --source . --log-opts="--all"

Gitleaks détecte par exemple une clé AWS :

# ❌ Trouvé par Gitleaks
AWS_SECRET_KEY = "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"
# ✅ Utiliser une variable d'environnement
import os
AWS_SECRET_KEY = os.environ.get("AWS_SECRET_KEY")

Guide Gitleaks | Guide TruffleHog

Intégration dans le pipeline CI/CD

Le SAST est plus efficace quand il s’exécute automatiquement à chaque changement de code.

En local (pre-commit)

Le développeur détecte les problèmes avant même de commit :

.pre-commit-config.yaml
repos:
- repo: https://github.com/gitleaks/gitleaks
rev: v8.18.0
hooks:
- id: gitleaks
- repo: https://github.com/returntocorp/semgrep
rev: v1.50.0
hooks:
- id: semgrep
args: ['--config', 'p/security-audit']

À chaque pull request

Le pipeline CI bloque la PR si des vulnérabilités critiques sont détectées :

name: SAST Scan
on: pull_request
jobs:
semgrep:
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: returntocorp/semgrep-action@713efdd345f3035192eaa63f56867b88e63e4e5d # v1
with:
config: p/security-audit
gitleaks:
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
fetch-depth: 0
- uses: gitleaks/gitleaks-action@ff98106e4c7b2bc287b24eaf42907196329070c7 # v2.3.9
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

Stratégie de blocage

Bloquer sur tous les findings paralyse les équipes. Une approche graduée :

SévéritéActionExemple
CriticalBloquer le mergeInjection SQL confirmée
HighBloquer sauf exception documentéeSecret hardcodé
MediumAlerter, ne pas bloquerAlgorithme crypto déprécié
LowInformerBest practice non suivie

Gérer les faux positifs

Les scanners SAST produisent des faux positifs : des alertes sur du code qui n’est pas réellement vulnérable. C’est leur principale limite.

Pourquoi des faux positifs ?

  • Le scanner ne comprend pas le contexte métier
  • Les données sont validées ailleurs (framework, middleware)
  • Le code est volontairement écrit ainsi (cas de test, exemple)
  • La règle est trop générique

Comment les gérer

1. Annotations dans le code

La plupart des outils supportent des commentaires pour ignorer une ligne :

# Semgrep
password = get_password() # nosemgrep: hardcoded-password
# Bandit
password = "test123" # nosec B105

2. Fichier de baseline

Geler les findings existants pour ne voir que les nouveaux :

Terminal window
# Gitleaks : créer une baseline
gitleaks detect --source . --report-path baseline.json
# Scanner en ignorant la baseline
gitleaks detect --source . --baseline-path baseline.json

3. Configuration des règles

Désactiver les règles trop bruyantes ou non pertinentes :

.semgrep.yml
rules:
- id: custom-rules
# Exclure certains chemins
paths:
exclude:
- tests/
- docs/

Avantages et limites

Avantages

  • Shift-left : détection au plus tôt, coût de correction minimal
  • Couverture complète : analyse tout le code, même le code mort
  • Reproductible : mêmes résultats à chaque exécution
  • Éducatif : les développeurs apprennent les bonnes pratiques
  • Pas d’environnement : fonctionne sans déployer l’application

Limites

  • Faux positifs : nécessite du tri et de la configuration
  • Pas de contexte runtime : ne voit pas les problèmes de configuration
  • Langages supportés : couverture variable selon les outils
  • Complexité : certaines failles nécessitent une compréhension du flux

Outils disponibles

Pour aller plus loin