Aller au contenu

Sécurité de la supply chain logicielle

Mise à jour :

En mars 2024, un développeur curieux remarque que sa connexion SSH prend 500 ms de plus que d’habitude. En creusant, il découvre une backdoor planquée dans XZ Utils, un utilitaire de compression présent sur quasiment tous les serveurs Linux. Le code malveillant permettait une exécution de code à distance via SSH. Cette attaque sophistiquée a été préparée pendant deux ans par un contributeur devenu mainteneur du projet.

Bienvenue dans le monde des attaques supply chain : l’attaquant ne cible plus directement votre application, il compromet un composant en amont pour toucher tous ceux qui en dépendent.

Pourquoi la supply chain est une cible prioritaire

Une attaque supply chain cible les composants utilisés pour construire un logiciel plutôt que le logiciel lui-même : dépendances (npm, PyPI, Go modules), outils de build, pipelines CI/CD, registres (Docker Hub, npm registry) ou infrastructure tierce (CDN, API externes).

L’idée est simple : compromettre un composant utilisé par 10 000 projets, c’est compromettre potentiellement 10 000 projets d’un coup.

Ce qui rend ces attaques redoutables :

FacteurImpact
Confiance impliciteOn installe des dépendances sans les auditer
Effet cascadeUne dépendance compromise se propage à tous ses consommateurs
Détection difficileLe code malveillant vient d’une source “légitime”
Surface énormeUn projet moderne = des centaines de dépendances transitives
PersistanceLes attaquants peuvent préparer une compromission sur des années

Qui est concerné

ProfilImplicationPriorité
DéveloppeurChoix des dépendances, épinglage des versionsQuotidienne
DevOps/SRESécurisation des pipelines CI/CD, runnersCritique
Architecte sécuritéPolitique SBOM, évaluation des risquesStratégique
RSSIConformité CRA/NIS2, gouvernance supply chainRéglementaire
Responsable produitAttestation de conformité, SBOM clientContractuelle

Les vecteurs d’attaque à connaître

Empoisonnement de dépendances

L’attaquant publie un package malveillant qui ressemble à un package légitime :

  • Typosquatting : package avec un nom proche (lodahs au lieu de lodash). Une faute de frappe à l’installation suffit.
  • Dependency confusion : package public avec le nom d’un package privé interne. Les gestionnaires privilégient souvent le registre public.
  • Maintainer takeover : reprise d’un package abandonné, puis injection de code malveillant lors d’une mise à jour anodine.

Compromission des pipelines CI/CD

Les pipelines ont accès aux secrets et peuvent modifier le code déployé :

  • Actions compromises : une action GitHub modifiée peut exfiltrer les secrets ou injecter du code dans les artefacts.
  • Secrets dans les logs : un script malveillant affiche les variables sensibles dans les logs publics.
  • Runners partagés : sur des runners mutualisés, un job malveillant accède aux données des jobs précédents.

Attaques sur les registres

  • Compromission de comptes mainteneurs : sans 2FA, un simple phishing suffit à publier une version malveillante.
  • Failles des registres : vulnérabilités permettant de modifier des packages sans authentification.
  • Modification des métadonnées : redirection vers du code malveillant sans toucher au code source.

Compromission d’infrastructure tierce

  • Rachat de domaines : un domaine légitime racheté par une entité malveillante (cf. Polyfill.io).
  • CDN compromis : injection de code dans tous les fichiers distribués.
  • Fournisseurs de services : compromettre un éditeur touche tous ses clients (cf. SolarWinds).

Attaques majeures 2024-2025

Les attaques supply chain ne sont pas nouvelles. En 1984, Ken Thompson démontrait déjà le concept dans “Reflections on Trusting Trust”. Mais 2024-2025 marque un tournant : attaques plus sophistiquées, mieux préparées, ciblant des composants critiques.

XZ Utils Backdoor (mars 2024)

CVE-2024-3094 — L’attaque supply chain la plus sophistiquée jamais documentée.

Un contributeur nommé “Jia Tan” a gagné la confiance du mainteneur pendant deux ans. Il a introduit du code malveillant dans les versions 5.6.0 et 5.6.1 de liblzma. La backdoor modifiait sshd pour permettre une exécution de code à distance.

Impact potentiel : accès root à distance sur tous les serveurs Linux.

Leçons :

  • La confiance open source repose sur peu de mainteneurs
  • Les attaques peuvent être préparées sur le très long terme
  • Un comportement anormal (500 ms de latence) peut révéler une compromission

Polyfill.io CDN (juin 2024)

Le domaine polyfill.io, utilisé par 100 000+ sites web, a été racheté par une entité malveillante. Le nouveau propriétaire a modifié le code servi pour rediriger vers des sites de phishing.

Leçons :

  • Les CDN tiers sont un vecteur sous-estimé
  • Un changement de propriétaire peut transformer un service légitime en menace
  • L’auto-hébergement des ressources critiques réduit la surface d’attaque

tj-actions/changed-files (mars 2025)

CVE-2025-30066 — L’attaque a commencé par la compromission de reviewdog/action-setup@v1, puis de tj-actions/changed-files. Les attaquants ont modifié toutes les versions (v1 à v45) pour exfiltrer les secrets CI/CD dans les logs.

Impact : des milliers de dépôts exposés, dont des projets d’entreprises comme Coinbase.

Leçons :

  • Les tags Git mutables (@v1) sont dangereux — toujours épingler sur un SHA
  • Une action compromise accède à tous les secrets du workflow
  • Effet cascade : une action peut en compromettre d’autres

Shai-Hulud npm Worm (août-novembre 2025)

Un malware auto-réplicant a infecté des packages npm populaires. Le script telemetry.js collectait credentials, clés SSH et wallets crypto. Si l’accès GitHub était disponible, il s’auto-propageait vers d’autres packages.

Impact : 500+ packages compromis, milliers de machines infectées.

Leçons :

  • Les scripts postinstall npm sont un vecteur majeur
  • Un malware auto-réplicant se propage de package en package
  • Les environnements de développement sont des cibles de choix

Normes et réglementations

Face à la multiplication des attaques, plusieurs standards définissent des exigences de sécurité pour la supply chain.

Réglementations obligatoires

RéglementationPérimètreExigences clésSanctions
EU Cyber Resilience ActProduits numériques vendus en UE (2027)SBOM obligatoire, secure by design, mises à jour de sécurité15M€ ou 2,5% CA
NIS2Secteurs critiques UE (2024)Évaluation risques fournisseurs, notification 24hResponsabilité dirigeants
Executive Order 14028Fournisseurs gouvernement USSBOM, attestation NIST SSDF, tests sécuritéExclusion marchés publics

Frameworks volontaires

FrameworkOrganisationObjectif
SLSA (Supply chain Levels for Software Artifacts)Google4 niveaux de maturité pour sécuriser la chaîne de build
NIST SSDF (SP 800-218)NISTPratiques de développement sécurisé
OpenSSF ScorecardLinux FoundationScore de posture sécurité des projets open source (0-10)

Stratégies de défense

1. Inventorier avec un SBOM

Un SBOM (Software Bill of Materials) inventorie tous les composants d’un logiciel. Quand une CVE tombe, on identifie en secondes si on est impacté.

Terminal window
# Générer un SBOM avec Syft
syft mon-image:latest -o cyclonedx-json > sbom.json
# Rechercher un composant
grep -l "xz-utils" *.sbom.json

2. Évaluer avant adoption

Avant d’ajouter une dépendance :

Critères manuels :

  • Activité du projet (dernier commit, fréquence des releases)
  • Nombre de mainteneurs (un seul = vulnérable au takeover)
  • Historique de sécurité (réactivité sur les CVE)
  • Légitimité (attention au typosquatting)

Outils automatiques :

Terminal window
# OpenSSF Scorecard : score 0-10
scorecard --repo=github.com/org/projet
# Un score < 5 doit alerter

3. Épingler les versions

Ne jamais utiliser de tags mutables. Toujours épingler sur un hash :

# ❌ Dangereux : tag mutable
- uses: actions/checkout@v4
# ✅ Sécurisé : SHA épinglé
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11

4. Scanner les vulnérabilités

Terminal window
# Scanner avec Grype
grype sbom:sbom.json --fail-on high
# Scanner avec Trivy
trivy image mon-image:latest

5. Signer et vérifier

Terminal window
# Signer une image avec Cosign
cosign sign mon-registry/mon-image:1.0.0
# Vérifier avant déploiement
cosign verify mon-registry/mon-image:1.0.0

6. Réduire la surface d’attaque

  • Minimiser les dépendances : implémenter soi-même quand c’est raisonnable
  • Auditer les dépendances transitives : npm ls, pip-audit
  • Auto-héberger les ressources critiques : pas de CDN tiers pour les scripts

7. Sécuriser les pipelines

Les pipelines CI/CD sont le vecteur d’attaque n°1 sur la supply chain. Ils ont accès aux secrets, au code, aux registres et aux environnements de production.

  • Runners éphémères : environnement neuf détruit après exécution
  • Isolation des secrets : séparation par environnement (dev/staging/prod)
  • 2FA obligatoire : sur tous les comptes avec accès aux dépôts
  • Revues de code : y compris pour .github/workflows/
  • Détection de secrets : Gitleaks, TruffleHog en CI

Pièges courants

PiègeConséquenceSolution
Faire confiance aux tags (@v1)Compromission silencieuseÉpingler sur SHA
Ignorer les dépendances transitivesVulnérabilité cachéeAuditer l’arbre complet
Scripts postinstall non auditésExécution de code arbitraireDésactiver ou auditer
Secrets en variables d’environnementExfiltration via logsUtiliser un vault
CDN tiers pour scripts critiquesInjection de codeAuto-héberger
Un seul mainteneur = confiance aveugleTakeover possibleÉvaluer avec Scorecard
SBOM généré une foisDrift avec la réalitéGénérer à chaque build

Outils disponibles

Standards et concepts

Outils de signature et attestation

Scanners de vulnérabilités

Détection de secrets

Pipelines CI/CD

À retenir

  1. Inventorier : générer un SBOM à chaque build pour savoir ce qui tourne
  2. Évaluer : OpenSSF Scorecard avant d’adopter une dépendance (score < 5 = alerte)
  3. Épingler : SHA pour les actions GitHub, versions exactes pour les dépendances
  4. Scanner : Trivy/Grype en CI, bloquer les vulnérabilités critiques
  5. Signer : Cosign pour garantir l’intégrité et la provenance des artefacts
  6. Isoler : runners éphémères, secrets séparés par environnement, 2FA obligatoire
  7. Anticiper : la question n’est plus “si” mais “quand” une dépendance sera compromise

Liens utiles

Guides internes

Ressources externes