Aller au contenu
Culture DevOps high
🚧 Section en cours de réécriture — Le contenu est en cours de restructuration et peut évoluer.

Tests de sécurité automatisés

12 min de lecture

En 2023, une étude de Snyk révèle que 84% des applications contiennent au moins une vulnérabilité connue dans leurs dépendances. Plus inquiétant : le temps moyen pour corriger une vulnérabilité critique est de 246 jours. Ces chiffres illustrent un décalage fondamental entre la vitesse de développement et la capacité à sécuriser le code.

La bonne nouvelle : l’automatisation des tests de sécurité permet de réduire drastiquement ce délai. L’enjeu n’est plus de choisir entre vélocité et sécurité, mais de les intégrer dans un même flux continu.

L’analyse de sécurité repose sur quatre approches complémentaires. Chacune détecte des catégories de vulnérabilités différentes, à des moments différents du cycle de développement. Comprendre leurs forces et limites est essentiel pour construire une stratégie efficace.

ApprocheCibleMomentCe qu’elle détecteLimites
SASTCode sourceDéveloppementInjections, secrets, patterns dangereuxFaux positifs, contexte d’exécution ignoré
DASTApplication déployéeStaging/ProdFailles exploitables, misconfigurationsCouverture limitée, lent
SCADépendancesBuildCVE dans les bibliothèques tiercesNe détecte que les vulnérabilités connues
FuzzingEntrées/APIsTestsComportements inattendus, crashs, edge casesGourmand en ressources

Le SAST (Static Application Security Testing) analyse le code sans l’exécuter. Il parse le code source, construit un modèle abstrait et recherche des patterns connus de vulnérabilités.

Le SAST excelle à trouver certaines catégories de problèmes :

CatégorieExemplesPourquoi SAST est efficace
InjectionsSQL, XSS, Command injectionPatterns reconnaissables : concaténation de strings avec input utilisateur
Secrets hardcodésAPI keys, tokens, passwordsPatterns regex : password = "...", formats connus (AWS, GitHub)
Crypto faibleMD5, SHA1, DESAppels à des fonctions connues comme obsolètes
Mauvaises pratiqueseval(), exec(), désérialisation non sécuriséeFonctions spécifiques blacklistées

Le SAST a des angles morts importants :

  • Contexte d’exécution : Le code user_input = request.get('name') suivi de db.query(f"SELECT * FROM users WHERE name = '{user_input}'") est une injection SQL évidente. Mais si l’input est validé trois fichiers plus loin, SAST peut ne pas faire le lien.

  • Faux positifs : Sans contexte, SAST signale des problèmes qui n’en sont pas. Un eval() utilisé sur une constante n’est pas dangereux.

  • Logique métier : SAST ne comprend pas que “un utilisateur ne devrait pas pouvoir voir les commandes d’un autre”.

Le SAST s’intègre à plusieurs niveaux du cycle de développement :

Point d’intégrationAvantageInconvénient
IDE (temps réel)Feedback immédiat, contexte fraisPeut ralentir l’éditeur
Pre-commitBloque avant le pushPeut frustrer si trop strict
CI (Pull Request)Revue systématiqueFeedback plus tardif
Scheduled (nightly)Analyse approfondieDétection retardée

Le DAST (Dynamic Application Security Testing) teste l’application en cours d’exécution. Il simule les actions d’un attaquant : envoie des requêtes malformées, tente des injections, explore les endpoints.

Le DAST trouve ce que le SAST manque :

CatégorieExemplesPourquoi DAST est nécessaire
Injections exploitablesSQL, XSS qui passent vraimentValide que la faille est réellement exploitable
MisconfigurationsHeaders manquants, CORS permissifConfiguration runtime, pas dans le code
Authentification faibleSession fixation, tokens prédictiblesComportement runtime
Fuites d’informationStack traces, versions exposéesRéponses HTTP réelles

Le DAST a aussi ses angles morts :

  • Couverture : Il ne teste que ce qu’il peut atteindre. Un endpoint non documenté ou une fonctionnalité derrière une authentification complexe peut être ignoré.

  • Lenteur : Contrairement au SAST qui analyse du texte, le DAST envoie des requêtes réelles. Un scan complet peut prendre des heures.

  • Environnement : Il faut une application déployée et fonctionnelle. Impossible de tester du code non encore intégré.

Le DAST s’utilise plus tard dans le cycle que le SAST :

EnvironnementUsageFréquence
Développement localTests ciblés sur nouvelles fonctionnalitésÀ la demande
Staging/Pre-prodScan complet avant releaseChaque release candidate
ProductionMonitoring continu, pentestHebdomadaire/mensuel

Le SCA (Software Composition Analysis) analyse les bibliothèques tierces utilisées par votre application. Il compare vos dépendances aux bases de données de vulnérabilités connues (CVE). C’est un pilier critique du DevSecOps moderne.

Le code que vous écrivez représente souvent moins de 20% de votre application. Le reste vient de dépendances : frameworks, bibliothèques, utilitaires. Chaque dépendance est un vecteur potentiel de vulnérabilités.

Exemples récents marquants :

  • Log4Shell (2021) : Vulnérabilité dans Log4j, présente dans des millions d’applications Java
  • Spring4Shell (2022) : Faille dans Spring Framework, framework Java le plus utilisé
  • Polyfill.io (2024) : Supply chain attack via un CDN JavaScript largement utilisé
InformationDescriptionUtilité
CVEVulnérabilités publiées avec identifiant uniqueIdentifier les failles connues
CVSSScore de sévérité (0-10)Prioriser par criticité
EPSSProbabilité d’exploitation (0-100%)Prioriser par risque réel
LicenceType de licence (MIT, GPL, propriétaire)Conformité juridique
Dépendances transitivesDépendances de vos dépendancesVisibilité sur la supply chain

Toutes les CVE ne se valent pas. Une stratégie efficace priorise selon plusieurs critères :

PrioritéCritèresAction
P0 - CritiqueCVSS ≥ 9.0 ET (EPSS > 10% OU KEV)Patch immédiat, bloquer le déploiement
P1 - HauteCVSS ≥ 7.0 ET dépendance directePatch sous 7 jours
P2 - MoyenneCVSS ≥ 4.0 OU dépendance transitive critiquePatch sous 30 jours
P3 - BasseCVSS < 4.0, pas d’exploit connuInclure dans maintenance régulière

Fuzzing : tests par injection de données aléatoires

Section intitulée « Fuzzing : tests par injection de données aléatoires »

Le fuzzing (ou fuzz testing) consiste à envoyer des données aléatoires ou semi-aléatoires à une application pour provoquer des comportements inattendus : crashs, fuites mémoire, exceptions non gérées.

Le fuzzing trouve ce que les autres méthodes manquent :

  • Edge cases : Que se passe-t-il avec une string de 10 millions de caractères ? Un entier négatif là où on attend un positif ?
  • Vulnérabilités inconnues : Contrairement au SAST/SCA qui cherchent des patterns connus, le fuzzing peut découvrir des vulnérabilités nouvelles (0-days).
  • Robustesse : Au-delà de la sécurité, le fuzzing améliore la qualité générale en trouvant des bugs de stabilité.
TypeDescriptionExemple
Dumb fuzzingDonnées totalement aléatoiresBytes aléatoires envoyés à un parser
Smart fuzzingDonnées aléatoires respectant un formatJSON valide avec valeurs aléatoires
Coverage-guidedAdapte les inputs pour explorer plus de codeAFL, libFuzzer
API fuzzingTeste les endpoints REST/GraphQLBurp, RESTler

Le fuzzing est gourmand en ressources. Il est particulièrement pertinent pour :

  • Code critique : Parsers, cryptographie, validation d’entrées
  • Bibliothèques partagées : Code utilisé par de nombreux projets
  • Avant release majeure : Validation approfondie
  • Nightly builds : En parallèle du développement

La question n’est pas si intégrer ces tests, mais comment les orchestrer efficacement. Voici une stratégie éprouvée :

  1. Pre-commit : détection de secrets

    Premier rempart, le plus à gauche. Bloque les commits contenant des secrets avant qu’ils n’atteignent le dépôt.

    .pre-commit-config.yaml
    repos:
    - repo: https://github.com/gitleaks/gitleaks
    rev: v8.18.0
    hooks:
    - id: gitleaks
  2. CI (Pull Request) : SAST + SCA

    Chaque PR est analysée automatiquement. Les vulnérabilités critiques bloquent le merge.

    # GitHub Actions
    security-scan:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v4
    # SAST avec Semgrep
    - name: Run Semgrep
    uses: returntocorp/semgrep-action@v1
    with:
    config: p/security-audit
    # SCA avec Trivy
    - name: Run Trivy
    run: |
    trivy fs --severity HIGH,CRITICAL --exit-code 1 .
  3. Staging : DAST

    Une fois l’application déployée en staging, les tests dynamiques peuvent s’exécuter.

    dast-scan:
    needs: deploy-staging
    runs-on: ubuntu-latest
    steps:
    - name: DAST scan
    run: |
    nuclei -u https://staging.example.com -t cves/ -severity critical,high
  4. Nightly : fuzzing et scans approfondis

    Les analyses longues s’exécutent la nuit, sans bloquer le développement.

    on:
    schedule:
    - cron: '0 2 * * *' # Tous les jours à 2h
    jobs:
    deep-scan:
    # Analyse complète, tous les seuils

Pour évaluer l’efficacité de vos tests de sécurité, suivez ces métriques :

MétriqueDescriptionCible
MTTD (Mean Time To Detect)Délai entre introduction et détection< 24h pour critique
MTTR (Mean Time To Remediate)Délai entre détection et correction< 7 jours pour critique
Taux de faux positifsAlertes non pertinentes< 10%
Couverture% du code analysé par SAST> 90%
Dette de vulnérabilitésVulnérabilités connues non corrigéesTendance descendante
  • SAST : Analyse le code source, rapide, beaucoup de faux positifs → développement
  • DAST : Teste l’application réelle, lent, peu de faux positifs → staging/prod
  • SCA : Analyse les dépendances, critique pour la supply chain → CI/CD
  • Fuzzing : Trouve les edge cases et 0-days → nightly/release
  • Combinaison : Aucune approche n’est suffisante seule