Aller au contenu

La confiance implicite dans les pipelines CI/CD

Mise à jour :

Imaginez que vous donniez les clés de votre maison à un inconnu simplement parce qu’il porte un uniforme de livreur. Absurde ? C’est pourtant ce que font la plupart des pipelines CI/CD : elles exécutent du code externe sans vérifier qui l’a écrit ni ce qu’il fait vraiment.

Ces trois incidents partagent un point commun : la confiance implicite accordée à des composants externes.

Ce qu’est vraiment la confiance implicite

La confiance implicite, c’est accorder une autorisation sans l’avoir consciemment décidée. C’est comme laisser la porte ouverte parce que “le quartier est sûr” — jusqu’au jour où quelqu’un entre.

Dans une pipeline CI/CD, elle se manifeste de multiples façons :

  • Utiliser une action tierce sans vérifier son code source
  • Télécharger des dépendances sans vérifier leur intégrité
  • Exécuter des scripts récupérés depuis Internet
  • Donner accès aux secrets de la pipeline à toutes les étapes

Ce qui rend la confiance implicite dangereuse, c’est son invisibilité. Personne n’a pris la décision consciente de faire confiance à ce composant. Il est simplement là, hérité d’un tutoriel, copié d’un autre projet, ajouté “parce que ça marchait”.

La différence avec la confiance explicite

Confiance impliciteConfiance explicite
”On a toujours utilisé cette action""On a audité cette action et accepté ses risques"
"Ça vient d’un mainteneur connu""On vérifie la signature de chaque release"
"C’est populaire, donc c’est sûr""On épingle la version et on surveille les changements"
"Le script est sur notre repo interne""Le script est signé et sa provenance est vérifiable”

Les zones de confiance d’une pipeline

Une pipeline CI/CD moderne interagit avec de nombreux composants externes. Chacun représente une zone de confiance qu’il faut identifier.

Pensez à votre pipeline comme à un restaurant : vous faites confiance au chef (votre code), mais aussi aux fournisseurs (dépendances), au livreur (actions), à la carte bancaire (tokens), aux assiettes (artefacts), aux recettes (scripts) et au frigo (cache). Si un seul maillon est compromis, tout le repas peut l’être.

  1. Les dépendances : Chaque npm install, pip install ou go get télécharge du code qui s’exécute dans votre environnement. Qui maintient cette dépendance ? Que se passe-t-il si le mainteneur perd son compte ?

  2. Les actions et plugins : Les actions GitHub, plugins Jenkins s’exécutent avec les permissions de la pipeline. Une action compromise peut lire tous les secrets, modifier le code, publier des artefacts malveillants.

  3. Les identités et tokens : Un secret volé donne accès à tout ce qu’il permet. Si le token a des permissions larges, l’attaquant aussi.

  4. Les artefacts produits : Si la pipeline est compromise, les artefacts produits (images, binaires) le sont aussi. Sans signatures, impossible de les distinguer des légitimes.

  5. Les scripts et configurations : Moins revus que le code applicatif, les scripts peuvent injecter du code, désactiver des contrôles, créer des accès persistants.

  6. Le cache : Un cache compromis peut réinjecter du code malveillant à chaque build, même après correction de la source originale.

  7. Les CDN et services externes : Charger des ressources depuis des CDN introduit une dépendance à leur sécurité. Le rachat de Polyfill.io l’a démontré.

Pourquoi la confiance aveugle persiste

Malgré les incidents répétés, la confiance implicite reste la norme. Plusieurs biais cognitifs l’expliquent.

L’anatomie d’une attaque par supply chain

Pour comprendre le danger, examinons comment un attaquant exploite la confiance implicite. L’affaire XZ Utils est un cas d’école parfait.

Les 5 phases d’une attaque supply chain :

  1. Phase 1 — Identification : L’attaquant repère un composant largement utilisé mais peu surveillé (mainteneur solo, projet utilitaire, peu de revue de code).

  2. Phase 2 — Infiltration : Il gagne la confiance pendant des mois via des contributions utiles, ou compromet le compte d’un mainteneur existant.

  3. Phase 3 — Injection : Le code malveillant est injecté — noyé dans un gros commit, obfusqué, ou conditionnel (s’active uniquement en CI/production).

  4. Phase 4 — Propagation : Le composant compromis est téléchargé automatiquement par tous les projets dépendants. Les pipelines accélèrent la propagation.

  5. Phase 5 — Exploitation : Exfiltration de secrets, injection de backdoors dans les artefacts, mouvement latéral, persistance.

Critères d’une cible idéale pour un attaquant :

  • Mainteneur unique ou épuisé
  • Projet utilitaire (moins scruté qu’un framework majeur)
  • Permissions élevées (système de fichiers, réseau, secrets)
  • Peu de revue de code sur les contributions

Les principes de la confiance explicite

Passer d’une confiance implicite à une confiance explicite demande un changement de paradigme.

1. Vérifier plutôt que supposer

Chaque composant externe doit être vérifié avant d’être utilisé :

  • Signature : le composant est-il signé par son auteur légitime ?
  • Provenance : peut-on tracer l’origine jusqu’au code source ?
  • Intégrité : le composant n’a-t-il pas été modifié depuis sa création ?

2. Minimiser les permissions

Chaque étape d’une pipeline ne devrait avoir accès qu’à ce dont elle a strictement besoin (moindre privilège). Un job de test n’a pas besoin des secrets de production. Une action de formatage n’a pas besoin d’écrire sur le repository.

3. Épingler les versions

Utiliser latest ou @v3 signifie accepter automatiquement tout changement futur. Épingler une version spécifique (ou mieux, un hash SHA) donne le contrôle sur ce qui s’exécute.

# ❌ Confiance implicite
uses: actions/checkout@v4
# ✅ Confiance explicite
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1

4. Surveiller les changements

Les dépendances évoluent. Un audit initial ne suffit pas :

  • Être alerté des nouvelles versions
  • Revoir les changements avant mise à jour
  • Détecter les comportements anormaux

5. Documenter les décisions de confiance

Quand l’équipe décide de faire confiance à un composant, cette décision doit être documentée :

  • Pourquoi ce composant ?
  • Quelles alternatives ont été considérées ?
  • Quels risques ont été acceptés ?
  • Qui est responsable de la surveillance ?

À retenir

  • La confiance implicite est invisible — Personne n’a consciemment décidé d’accorder cette confiance.
  • Sept zones de confiance existent dans une pipeline : dépendances, actions, identités, artefacts, scripts, cache, services externes.
  • Les biais cognitifs nous piègent — Automatisation, familiarité, popularité, pression du temps.
  • Les attaques supply chain sont patientes — Infiltration, confiance, injection, propagation.
  • La confiance explicite repose sur : vérification, permissions minimales, épinglage, surveillance, documentation.

Liens utiles