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 implicite | Confiance 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.
-
Les dépendances : Chaque
npm install,pip installougo getté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 ? -
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.
-
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.
-
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.
-
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.
-
Le cache : Un cache compromis peut réinjecter du code malveillant à chaque build, même après correction de la source originale.
-
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 :
-
Phase 1 — Identification : L’attaquant repère un composant largement utilisé mais peu surveillé (mainteneur solo, projet utilitaire, peu de revue de code).
-
Phase 2 — Infiltration : Il gagne la confiance pendant des mois via des contributions utiles, ou compromet le compte d’un mainteneur existant.
-
Phase 3 — Injection : Le code malveillant est injecté — noyé dans un gros commit, obfusqué, ou conditionnel (s’active uniquement en CI/production).
-
Phase 4 — Propagation : Le composant compromis est téléchargé automatiquement par tous les projets dépendants. Les pipelines accélèrent la propagation.
-
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 impliciteuses: actions/checkout@v4
# ✅ Confiance expliciteuses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.14. 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
- Introduction à la supply chain logicielle — vue d’ensemble des enjeux
- SLSA — framework de niveaux de sécurité pour la supply chain
- Le SBOM de A à Z — inventorier ses dépendances
- Confiance transitive — comprendre les chaînes de confiance
- Principe du moindre privilège — réduire la surface d’attaque
- OWASP Top 10 CI/CD — les risques majeurs des pipelines
- OpenSSF Scorecard — évaluer la santé d’un projet open source