Objectifs pédagogiques¶
- Comprendre les risques liés aux dépendances vulnérables
- Utiliser npm audit pour analyser les dépendances JavaScript/Node.js
- Utiliser Grype pour scanner les vulnérabilités dans différents environnements
- Interpréter les rapports de vulnérabilités
- Mettre en place des stratégies de remédiation
- Intégrer les scans de dépendances dans une pipeline CI/CD
SCA & Théorie¶
Les vulnérabilités dans les dépendances¶
Pourquoi les dépendances sont-elles un risque ?
Les applications modernes dépendent massivement de bibliothèques tierces.
Un projet Node.js moyen peut avoir des centaines, voire des milliers de dépendances (directes et transitives).
Statistiques clés :
- Plus de 80% des bases de code contiennent au moins une vulnérabilité dans leurs dépendances
- En moyenne, une application contient 10-20 vulnérabilités connues dans ses dépendances
- Les attaques sur la supply chain (chaîne d'approvisionnement) sont en augmentation de 650% depuis 2021
Software Composition Analysis (SCA)¶
Le SCA (Software Composition Analysis) est le processus d'identification et d'analyse des composants open source utilisés dans une application.
Objectifs du SCA :
- Inventorier toutes les dépendances (directes et transitives)
- Identifier les vulnérabilités connues (CVE)
- Vérifier les licences des dépendances
- Détecter les composants obsolètes ou non maintenus
- Assurer la conformité réglementaire
Sources de données de vulnérabilités :
- CVE (Common Vulnerabilities and Exposures)
- Bases NVD (National Vulnerability Database)
- Conseils de sécurité éditeurs (Security Advisories)
- Bases internes (pour Sonatype, Snyk, etc.)
Présentation des outils - NPM¶
npm audit est l'outil intégré à npm pour analyser les vulnérabilités dans les dépendances Node.js
Caractéristiques :
- Intégré nativement à npm (pas d'installation nécessaire)
- Analyse le fichier package-lock.json
- S'appuie sur la base de données GitHub Advisory Database
- Propose des corrections automatiques
Limites :
- Spécifique à l'écosystème Node.js/JavaScript
- Ne détecte pas les malwares référencés dans d'autres bases de données
Présentation des outils - Grype¶
Grype est un scanner de vulnérabilités open-source développé par Anchore
Caractéristiques :
- Multi-langage et multi-écosystème (npm, pip, Maven, Go, Ruby, etc.)
- Scan d'images Docker
- Scan de systèmes de fichiers
- Scan de SBOM (Software Bill of Materials)
- Base de données de vulnérabilités exhaustive et régulièrement mise à jour
- Rapports en plusieurs formats (JSON, table, SARIF, etc.)
Avantages par rapport à npm audit :
- Support multi-langage
- Scan d'images conteneur complètes
- Plus de sources de données de vulnérabilités
- Meilleure détection des dépendances du système d'exploitation
Comparaison des outils - NPM Audit vs Grype¶
| Critère | npm audit | Grype |
|---|---|---|
| Écosystèmes | Node.js uniquement | Multi-langage (npm, pip, Maven, Go, etc.) |
| Installation | Natif avec npm | Installation séparée |
| Images Docker | Non | Oui |
| SBOM | Non | Oui (via Syft) |
| Corrections auto | Oui (npm audit fix) | Non |
| Sources de données | GitHub Advisory | NVD, GitHub, OSV, etc. |
| Performance | Rapide | Légèrement plus lent |
| Formats de sortie | JSON, text | JSON, table, SARIF, CycloneDX, etc. |
| Exceptions | Limitées | Fichier de config .grype.yaml |
| Coût | Gratuit | Gratuit (open-source) |
NPM Audit & Pratique¶
NPM Audit: Utilisation de base¶
Créer un projet de test
# Créer un nouveau répertoire
mkdir tp-npm-audit
cd tp-npm-audit
# Initialiser un projet npm
npm init -y
# Installer quelques dépendances (dont certaines avec des vulnérabilités connues)
npm install express@4.16.0
npm install lodash@4.17.11
npm install request@2.88.0
Note : Ces versions anciennes sont volontairement choisies pour avoir des vulnérabilités à détecter.
NPM Audit: Utilisation de base¶
Lancer un audit
Sortie attendue
# npm audit report
lodash <=4.17.20
Severity: high
Prototype Pollution in lodash - https://github.com/advisories/GHSA-fvqr-27wr-82fm
Prototype Pollution in lodash - https://github.com/advisories/GHSA-p6mc-m468-83gw
fix available via `npm audit fix`
node_modules/lodash
request <=2.88.2
Severity: moderate
Server-Side Request Forgery in Request - https://github.com/advisories/GHSA-p8p7-x288-28g6
No fix available
node_modules/request
3 vulnerabilities (1 moderate, 2 high)
To address issues that do not require attention, run:
npm audit fix
NPM Audit: Utilisation de base¶
Structure du rapport :
- Nom du package : dépendance affectée
- Plage de versions vulnérables : versions impactées
- Severity (sévérité) : critical, high, moderate, low
- Description : type de vulnérabilité
- Lien GitHub Advisory : détails complets
- Fix available : correctif disponible ou non
Niveaux de sévérité :
- Critical : exploitation facile avec impact majeur
- High : exploitation possible avec impact significatif
- Moderate : impact limité ou exploitation complexe
- Low : impact minimal
Obtenir plus de détails
# Format JSON détaillé
npm audit --json
# Format JSON avec toutes les informations
npm audit --json > audit-report.json
NPM Audit: Utilisation de base¶
Correction des vulnérabilités
Correction automatique :
# Corriger les vulnérabilités sans breaking changes
npm audit fix
# Corriger avec des breaking changes (attention !)
npm audit fix --force
Correction manuelle :
# Voir les dépendances obsolètes
npm outdated
# Mettre à jour une dépendance spécifique
npm update lodash
# Installer une version spécifique
npm install lodash@4.17.21
NPM Audit : Options avancées¶
Filtrer par niveau de sévérité
# Audit avec seuil de sévérité (échoue si vulnerabilités >= moderate)
npm audit --audit-level=moderate
# Seuils possibles : low, moderate, high, critical
npm audit --audit-level=high
Audit en mode production uniquement
Générer un rapport détaillé
# Format lisible
npm audit > audit-report.txt
# Format JSON pour automatisation
npm audit --json > audit-report.json
# Format parseable pour scripts
npm audit --parseable
NPM Audit : Intégration CI/CD¶
Exemple pour GitLab CI
Créer un fichier .gitlab-ci.yml :
stages:
- security
npm-audit:
stage: security
image: node:18
script:
- npm ci
- npm audit --audit-level=high
# Alternative avec rapport JSON
- npm audit --json > npm-audit-report.json
artifacts:
when: always
reports:
dependency_scanning: npm-audit-report.json
paths:
- npm-audit-report.json
allow_failure: false # La pipeline échoue si vulnérabilités high/critical
NPM Audit : Intégration CI/CD¶
Exemple pour GitHub Actions
Créer .github/workflows/security.yml :
name: Security Audit
on:
push:
branches: [ main, develop ]
pull_request:
branches: [ main ]
jobs:
npm-audit:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: '18'
- name: Install dependencies
run: npm ci
- name: Run npm audit
run: npm audit --audit-level=moderate
- name: Generate audit report
if: always()
run: npm audit --json > npm-audit-report.json
- name: Upload audit report
if: always()
uses: actions/upload-artifact@v3
with:
name: npm-audit-report
path: npm-audit-report.json
NPM Audit : Gestion des exceptions¶
Parfois, une vulnérabilité ne peut pas être corrigée immédiatement (pas de patch disponible, dépendance transitoire, etc.)
Utiliser npm-audit-resolver (outil tiers)
# Installation
npm install -g npm-audit-resolver
# Générer un fichier d'audit
npm-audit-resolver
# Résoudre interactivement les vulnérabilités
# Créer des exceptions dans audit-resolve.json
Ignorer temporairement des vulnérabilités
Note : npm ne fournit pas de mécanisme natif d'ignore. Utilisez des wrappers ou acceptez l'échec en CI.
Grype & Pratique¶
Installation de Grype¶
Installation sur Linux
curl -sSfL https://raw.githubusercontent.com/anchore/grype/main/install.sh | sh -s -- -b /usr/local/bin
Installation sur macOS avec Homebrew
Installation sur Windows
Grype - Utilisation de base¶
Scanner un répertoire
# Scanner le répertoire courant
grype .
# Scanner un répertoire spécifique
grype /path/to/project
# Scanner avec un format de sortie spécifique
grype . -o table
grype . -o json
grype . -o sarif
Grype - Comprendre les résultats¶
Format de sortie table (par défaut)
NAME INSTALLED FIXED-IN TYPE VULNERABILITY SEVERITY
lodash 4.17.11 4.17.12 npm CVE-2019-10744 high
minimist 1.2.0 1.2.6 npm CVE-2021-44906 critical
node-fetch 2.6.0 2.6.7 npm CVE-2022-0235 high
Colonnes :
- NAME : nom du package vulnérable
- INSTALLED : version installée
- FIXED-IN : version où la vulnérabilité est corrigée
- TYPE : type de package (npm, deb, apk, python, java-archive, etc.)
- VULNERABILITY : identifiant CVE ou GHSA
- SEVERITY : critical, high, medium, low, negligible, unknown
Grype - Options avancées¶
Filtrer par sévérité
# Afficher uniquement les vulnérabilités high et critical
grype . --fail-on high
# Échouer uniquement sur les vulnérabilités critical
grype . --fail-on critical
Grype - Options avancées¶
Exclure des packages
# Ignorer certains packages
grype . --exclude 'lodash'
# Utiliser un fichier de configuration
cat > .grype.yaml <<EOF
ignore:
- vulnerability: CVE-2019-10744
package:
name: lodash
version: 4.17.11
reason: "Not exploitable in our context"
EOF
grype . -c .grype.yaml
Grype - Options avancées¶
Scanner plusieurs types d'artifacts
# Scanner une image Docker avec son filesystem
grype docker:nginx:latest
# Scanner un fichier tar
grype docker-archive:image.tar
# Scanner un OCI directory
grype oci-dir:./path/to/oci
# Scanner un registry
grype registry:myregistry.com/myimage:tag
Grype : intégration CI/CD¶
Exemple pour GitLab CI
stages:
- security
grype-scan:
stage: security
image: anchore/grype:latest
script:
# Scanner le projet
- grype . -o json --file grype-report.json
# Échouer si vulnérabilités high ou critical
- grype . --fail-on high
artifacts:
when: always
paths:
- grype-report.json
reports:
# GitLab supporte le format SARIF
- grype . -o sarif > grype-report.sarif
allow_failure: false
Grype : intégration CI/CD¶
Exemple pour GitHub Actions
name: Grype Vulnerability Scan
on:
push:
branches: [ main, develop ]
pull_request:
branches: [ main ]
jobs:
grype-scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Run Grype vulnerability scanner
uses: anchore/scan-action@v3
id: grype
with:
path: "."
fail-build: true
severity-cutoff: high
- name: Upload Grype results to GitHub Security
uses: github/codeql-action/upload-sarif@v2
if: always()
with:
sarif_file: ${{ steps.grype.outputs.sarif }}
Exercices pratiques¶
Exercice 1 : Audit avec npm¶
Objectif : Identifier et corriger des vulnérabilités avec npm audit
- Créez un nouveau projet Node.js
- Installez les dépendances suivantes (versions vulnérables) :
- Lancez npm audit et analysez le rapport
- Identifiez les vulnérabilités critical et high
- Corrigez-les avec npm audit fix
- Pour celles qui ne peuvent pas être corrigées automatiquement, mettez à jour manuellement
Exercice 2 : Scan multi-langage avec Grype¶
Objectif : Utiliser Grype pour scanner différents types de projets
- Créez un projet contenant :
- Des dépendances Node.js (package.json)
- Des dépendances Python (requirements.txt avec des versions anciennes)
- Exemple : flask==1.0.0, requests==2.20.0
- Lancez Grype sur le projet complet
- Comparez les résultats avec npm audit (pour la partie Node.js)
- Générez un rapport JSON complet
- Filtrez les résultats pour afficher uniquement les vulnérabilités critical
Exercice 3 : Pipeline de sécurité complète¶
Objectif : Intégrer npm audit et Grype dans une pipeline CI/CD
- Créez un projet Node.js avec des tests
- Créez une pipeline GitLab CI ou GitHub Actions avec :
- Stage de sécurité (npm audit)
- Stage de sécurité (Grype)
- Configurez la pipeline pour échouer si des vulnérabilités high sont détectées
- Testez en introduisant volontairement une dépendance vulnérable
- Configurez des rapports en artifacts