La SCA (Software Composition Analysis) inventorie les bibliothèques tierces que votre application embarque, puis les confronte aux vulnérabilités publiées. Elle couvre le code que vous n'avez pas écrit, souvent le plus volumineux de votre livraison. Cette leçon s'adresse à un développeur ou un DevOps qui veut savoir ce qu'un scanner SCA lit, comment lire son rapport, et comment le placer dans un pipeline sans le transformer en alarme permanente. Les exemples sont relevés avec Trivy 0.74.0 et Grype 0.119.0 sur un vrai projet npm.
Ce que vous allez apprendre
Section intitulée « Ce que vous allez apprendre »- Comprendre ce qu'un scanner SCA lit et à quelles bases il compare l'inventaire
- Distinguer dépendances directes et transitives à partir d'un lockfile
- Interpréter un rapport réel et en tirer la bonne correction
- Bloquer un build sur les vulnérabilités graves, et seulement elles
- Encadrer une exception par une justification et une date d'expiration
- Rattacher ce contrôle à l'exigence SOCLE-APP-AST-3 du référentiel SOCLE
Qu'est-ce que la SCA ?
Section intitulée « Qu'est-ce que la SCA ? »La SCA répond à une question simple : « quelles bibliothèques externes mon application embarque-t-elle, et lesquelles portent une faille connue ? ». Elle ne lit pas votre code comme le fait le SAST : elle lit la liste des composants, avec leurs versions exactes, et la compare aux bases de vulnérabilités. La fuite d'Equifax en 2017 en est le cas d'école : une version connue vulnérable d'Apache Struts, une dépendance non mise à jour, qu'un scanner SCA aurait signalée.
| Aspect | SAST | SCA |
|---|---|---|
| Cible | Code écrit par l'équipe | Code des dépendances |
| Méthode | Motifs et flux de données dans le code | Versions confrontées aux bases de vulnérabilités |
| Trouve | Failles introduites par vos développeurs | Failles héritées des bibliothèques |
| Exemple | Injection SQL dans votre route | lodash 4.17.20, CVE-2021-23337 |
Pourquoi la SCA est-elle devenue indispensable ?
Section intitulée « Pourquoi la SCA est-elle devenue indispensable ? »Deux mouvements se combinent. Une application tire beaucoup plus de
composants qu'elle n'en déclare : mesuré sur le projet de test, 2
dépendances directes (express et lodash) produisent un lockfile de 51
paquets. Et les vulnérabilités sont publiées en continu : un composant sain
le jour de la livraison peut porter une CVE le mois suivant, sans qu'une
ligne de votre code ait changé. Sans inventaire automatisé, personne ne peut
suivre ce rythme à la main.
Une CVE (Common Vulnerabilities and Exposures) est l'identifiant public d'une faille, et son score CVSS en estime la gravité. La leçon CVE, CVSS et EPSS explique comment les lire et les prioriser.
Comment fonctionne un scanner SCA ?
Section intitulée « Comment fonctionne un scanner SCA ? »Un scanner SCA ne télécharge pas le code de vos dépendances pour l'analyser : il travaille sur leur inventaire. C'est ce qui le rend rapide, et c'est aussi ce qui le rend dépendant de la qualité de cet inventaire, d'où l'importance du lockfile.
-
Extraction de l'inventaire : le scanner lit les fichiers de dépendances, de préférence les lockfiles, qui figent les versions exactes :
package-lock.json,poetry.lock,go.sum,Cargo.lock. Un simplerequirements.txtsans versions figées ne dit pas ce qui sera réellement installé. -
Arbre des dépendances : le lockfile contient aussi les dépendances transitives, celles de vos dépendances, avec leurs versions.
-
Comparaison aux bases : chaque couple (paquet, version) est confronté aux bases publiques, comme la NVD du NIST, la GitHub Advisory Database ou OSV, qui agrège les avis de nombreux écosystèmes.
-
Rapport : pour chaque correspondance, l'identifiant (CVE ou GHSA), la sévérité, la version installée et la version corrigée quand elle existe.
Un vrai rapport SCA, lu ligne à ligne
Section intitulée « Un vrai rapport SCA, lu ligne à ligne »Le projet de test déclare deux dépendances figées dans son package.json, puis
npm install --package-lock-only produit le lockfile complet. Les deux
scanners lisent ce lockfile.
{ "name": "demo-sca", "version": "1.0.0", "private": true, "dependencies": { "express": "4.17.1", "lodash": "4.17.20" }}IMG="aquasec/trivy:0.74.0@sha256:62b1e65e8869bc4b4c6aa4fa2b21595256c7c2f6018a9d9ad61caf87187c1969"docker run --rm -v "$PWD:/src" -w /src "$IMG" fs --scanners vuln .Trivy remonte 19 vulnérabilités : 7 HIGH, 6 MEDIUM, 6 LOW, aucune
CRITICAL. Grype, sur le même lockfile, en trouve 19 également, avec la
même répartition. Voici les lignes de lodash, extraites du tableau de Trivy :
Total: 19 (UNKNOWN: 0, LOW: 6, MEDIUM: 6, HIGH: 7, CRITICAL: 0)│ lodash │ CVE-2021-23337 │ HIGH │ 4.17.20 │ 4.17.21 │ nodejs-lodash: command injection via template ││ │ CVE-2026-4800 │ │ │ 4.18.0 │ lodash: lodash: Arbitrary code execution via untrusted input ││ │ CVE-2020-28500 │ MEDIUM │ │ 4.17.21 │ nodejs-lodash: ReDoS via the toNumber, trim and trimEnd ││ │ CVE-2025-13465 │ │ │ 4.17.23 │ lodash: prototype pollution in _.unset and _.omit functions │Trois enseignements se lisent dans ces quatre lignes. D'abord, la nature exacte
de la faille compte : CVE-2021-23337 est une injection de commande via
_.template, pas une pollution de prototype, et son exploitation suppose que
votre code passe une entrée externe à cette fonction. Ensuite, une même
bibliothèque porte souvent plusieurs vulnérabilités corrigées dans des
versions différentes : passer à 4.17.21 ne suffit pas, la colonne de droite
mène à 4.18.0. Enfin, le tableau fusionne les cellules identiques : une
case de sévérité vide reprend celle de la ligne du dessus, et
CVE-2026-4800 est donc HIGH, pas sans sévérité.
Dépendances directes ou transitives ?
Section intitulée « Dépendances directes ou transitives ? »Une dépendance directe est déclarée dans votre package.json. Une
dépendance transitive est tirée par l'une d'elles. Sur le projet de test,
12 des 19 vulnérabilités se trouvent dans des transitives, comme qs,
send ou path-to-regexp, que personne n'a choisies. Le lockfile dit qui les
tire : qs 6.7.0 est demandé à la fois par express et par body-parser.
demo-sca├── express 4.17.1 (directe)│ ├── body-parser (transitive)│ │ └── qs 6.7.0 (transitive)│ ├── qs 6.7.0 (transitive)│ └── send (transitive)└── lodash 4.17.20 (directe)La conséquence est pratique : on ne corrige presque jamais une transitive en
l'ajoutant à la main. On monte la dépendance directe qui la tire, ici
express, ou on force la version avec le mécanisme du gestionnaire de paquets
(overrides pour npm), en le documentant.
Intégrer la SCA dans le pipeline
Section intitulée « Intégrer la SCA dans le pipeline »Le scan SCA a sa place à trois moments : sur le poste avant de pousser, à
chaque merge request pour bloquer, et en surveillance continue pour ce
qui est déjà livré. Le piège est le même qu'en SAST : sans option dédiée, les
deux scanners sortent en code 0 quoi qu'ils trouvent. Mesuré : Trivy sans
--exit-code sort en 0 malgré 19 vulnérabilités, Grype sans --fail-on aussi.
# Sur le postetrivy fs --scanners vuln .grype dir:.Le job utilise l'image officielle de Trivy, épinglée par digest, plutôt
qu'une action tierce : moins de code auquel faire confiance dans le pipeline.
permissions: {} retire tous les droits par défaut, contents: read
suffit pour cloner.
name: SCA
on: pull_request:
permissions: {}
jobs: trivy: runs-on: ubuntu-24.04 permissions: contents: read container: image: aquasec/trivy:0.74.0@sha256:62b1e65e8869bc4b4c6aa4fa2b21595256c7c2f6018a9d9ad61caf87187c1969 steps: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - name: Trivy, échec sur HIGH et CRITICAL run: trivy fs --scanners vuln --severity CRITICAL,HIGH --exit-code 1 .Même logique sur GitLab : image épinglée, sévérités filtrées, code de
sortie explicite. Mesuré : avec --severity CRITICAL,HIGH --exit-code 1,
le projet de test fait échouer le job en code 1.
sca: stage: test image: name: aquasec/trivy:0.74.0@sha256:62b1e65e8869bc4b4c6aa4fa2b21595256c7c2f6018a9d9ad61caf87187c1969 entrypoint: [""] script: - trivy fs --scanners vuln --severity CRITICAL,HIGH --exit-code 1 . rules: - if: $CI_PIPELINE_SOURCE == "merge_request_event" allow_failure: falseGrype fait le même travail avec l'option --fail-on, qui fixe la sévérité
à partir de laquelle le scan échoue. Mesuré : --fail-on high sur le projet
de test sort en code 2, valeur que la CI interprète comme un échec.
grype dir:. --fail-on highL'image de Trivy a pour point d'entrée le binaire trivy lui-même : sur
GitLab, entrypoint: [""] le neutralise pour que le script du job s'exécute
dans un shell. Sur GitHub Actions, un job container: lance ses étapes dans
un shell du conteneur, sans ce réglage.
Les images de conteneur
Section intitulée « Les images de conteneur »La SCA s'applique aussi aux images : elles embarquent les dépendances de
l'application et les paquets du système de base. La commande change de cible,
trivy image ou grype suivi du nom de l'image, et l'image scannée se
désigne par digest, sinon le rapport ne dit pas quelle image il a lue. Le
scan d'image est détaillé dans la leçon Trivy
du module conteneurs.
La surveillance continue
Section intitulée « La surveillance continue »Un scan en CI ne voit que ce qui passe dans le pipeline. Une image déployée il y a six mois ne repasse pas en CI, alors que de nouvelles CVE la concernent peut-être. La réponse est un inventaire conservé, le SBOM, qu'un outil comme Dependency-Track réexamine à chaque publication de vulnérabilité. Le SBOM a sa propre leçon dans le module supply chain.
Bloquer sans paralyser
Section intitulée « Bloquer sans paralyser »Bloquer sur toutes les vulnérabilités paralyse les équipes, ne bloquer sur
aucune revient à ne pas scanner. Une politique raisonnable bloque les
sévérités CRITICAL et HIGH, ouvre un ticket pour les MEDIUM, et passe les
LOW en revue. L'option --ignore-unfixed de Trivy écarte les vulnérabilités
sans version corrigée, pour ne pas bloquer sur ce qu'on ne peut pas réparer ;
sur le projet de test, elle ne retire rien, car les 19 vulnérabilités ont
toutes un correctif publié.
| Sévérité | Action | Délai indicatif |
|---|---|---|
| CRITICAL | Bloquer le build | Correction immédiate |
| HIGH | Bloquer le build | Correction avant la fusion |
| MEDIUM | Ticket avec échéance | Sprint suivant |
| LOW | Revue périodique | Selon le contexte |
Une exception doit expirer
Section intitulée « Une exception doit expirer »Certaines vulnérabilités ne s'appliquent pas à votre usage : la fonction vulnérable n'est jamais appelée, ou pas avec une entrée externe. L'exception est alors légitime, à condition d'être justifiée et datée. Trivy le permet nativement, avec deux fichiers dont le comportement diffère.
vulnerabilities: - id: CVE-2021-23337 statement: "_.template n'est jamais appelé avec une entrée externe ; revue le 2026-12-01" expired_at: 2027-01-01trivy fs --scanners vuln --ignorefile .trivyignore.yaml .Mesuré : avec cette exception, le rapport passe de 19 à 18 vulnérabilités ;
avec une date expired_at dépassée, la CVE réapparaît d'elle-même. Piège à
connaître : le format YAML n'est lu qu'avec --ignorefile, alors que
l'ancien format texte, .trivyignore, est lu par défaut. Un .trivyignore.yaml
posé sans l'option n'a aucun effet, et l'équipe croit à tort son exception
active.
Mettre à jour, avant tout
Section intitulée « Mettre à jour, avant tout »La meilleure exception reste celle qu'on n'a pas besoin d'écrire. Des outils comme Dependabot ou Renovate ouvrent des merge requests de mise à jour, une par dépendance ou par groupe, que la CI valide avant fusion. Ne négligez pas les dépendances de développement : un outil de test ou de build compromis s'exécute dans le pipeline, avec ses secrets.
Choisir un outil SCA
Section intitulée « Choisir un outil SCA »Trivy et Grype, les deux scanners mesurés ici, sont libres et tournent en local ; ils couvrent l'essentiel des besoins d'une équipe. Les autres outils répondent à des besoins différents : une plateforme de suivi dans le temps, ou un service commercial avec correction automatique.
| Outil | Type | Point fort | Cas d'usage |
|---|---|---|---|
| Trivy | CLI, libre | Un binaire pour dépendances, images et IaC | Scan CI universel |
| Grype | CLI, libre | Couplé à Syft pour les SBOM | Scan d'images et de SBOM |
| OSV-Scanner | CLI, libre | Base OSV, très large couverture | Projets multi-écosystèmes |
| Dependency-Track | Plateforme, libre | Suivi continu à partir des SBOM | Gouvernance d'un parc |
| Snyk | SaaS, commercial | Intégrations, correctifs proposés | Équipes avec budget |
Les limites de la SCA
Section intitulée « Les limites de la SCA »La SCA ne voit que ce qui est publié : une faille non encore divulguée, une 0-day, lui échappe par construction. Elle signale une vulnérabilité présente dans une version, pas une vulnérabilité atteignable par votre code : une CVE dans une fonction jamais appelée reste dans le rapport. Elle dépend aussi de l'inventaire : sans lockfile, ou avec un binaire copié à la main dans le dépôt, elle rate des composants. Elle complète donc le SAST et le DAST, elle ne les remplace pas.
À retenir
Section intitulée « À retenir »- La SCA confronte l'inventaire de vos dépendances aux vulnérabilités publiées ; elle ne lit pas votre code.
- Le lockfile est la source de vérité : 2 dépendances directes tiraient 51 paquets.
- La majorité des vulnérabilités du projet de test, 12 sur 19, étaient dans des transitives.
- On corrige une transitive en montant la dépendance directe qui la tire.
- Sans
--exit-code(Trivy) ou--fail-on(Grype), le scan ne bloque rien. - Une exception se justifie et expire :
.trivyignore.yamlexige--ignorefile. - La SCA ne voit ni les 0-day ni l'atteignabilité réelle d'une faille.
- Preuve attendue par SOCLE-APP-AST-3 : les constats SCA suivis dans le processus de gestion des vulnérabilités.
Contrôle de connaissances
Section intitulée « Contrôle de connaissances »Vérifiez que l'essentiel de cette leçon est acquis. Les questions portent uniquement sur ce qui vient d'être expliqué ici.
Contrôle de connaissances
Validez vos connaissances avec ce quiz interactif
Informations
- Le chronomètre démarre au clic sur Démarrer
- Questions à choix multiples, vrai/faux et réponses courtes
- Vous pouvez naviguer entre les questions
- Les résultats détaillés sont affichés à la fin
Lance le quiz et démarre le chronomètre
Vérification
(0/0)Score par domaine
Un domaine regroupe plusieurs guides et reçoit plusieurs questions : son score est plus fiable qu'un score par thème, qui porte souvent sur une seule question.
Bilan
Points forts
Aucun sujet réussi à 80 % sur au moins deux questions pour l’instant.
Points faibles
Aucun sujet sous le seuil de réussite.
À faire ensuite
Des indices pour retenter votre chance ?
Continuer le cours : Comprendre CVE, CVSS et EPSS
Nouveau quiz complet avec des questions aléatoires
Retravailler uniquement les questions ratées
Retour à la liste des certifications