Ce qu’un attaquant pourrait faire de votre pipeline en une heure
Si quelqu’un accédait à votre système de build pendant une heure, que pourrait-il emporter, et que pourrait-il modifier ?
Illustration conceptuelle de trois façons de pénétrer dans un pipeline de build. Ce n’est le schéma d’aucun système réel. Les libellés de l’image sont en anglais et font partie de l’illustration.
Un pipeline CI/CD est la chaîne automatisée qui construit, teste et livre votre logiciel. Pour faire ce travail, il détient votre code source, les secrets nécessaires pour atteindre d’autres systèmes et le droit de déployer. Un secret désigne ici un mot de passe, un jeton ou une clé qui prouve votre identité auprès d’un autre service.
Cette combinaison fait du pipeline une cible de choix. Un attaquant qui l’atteint n’a peut-être même pas besoin de s’introduire dans votre application. Il peut prendre les clés, ou modifier ce qui est livré.
Trois incidents survenus au cours de la même quinzaine montrent comment cela se produit. Ils semblent différents, mais ils aboutissent au même endroit. Cet article les passe en revue un par un, puis vous propose une vérification d’une heure.
Pourquoi les attaquants s’en prennent aux pipelines
Un pipeline bénéficie de la confiance par conception. Il peut lire du code privé, appeler des services cloud et publier des paquets, et personne ne surveille chacune de ses étapes. Un secret stocké dans un pipeline est souvent plus puissant qu’un secret présent sur l’ordinateur portable d’un développeur.
Une attaque de la chaîne d’approvisionnement consiste à attaquer un élément dont dépend votre logiciel, plutôt que votre logiciel lui-même. Dans cet article, il s’agit des fichiers de workflow de votre dépôt, des paquets que votre build installe et du système de CI lui-même. L’attaquant vous atteint par une porte que vous avez déjà ouverte.
Alternative textuelle accessible pour cette figure
Un pipeline se déroule de gauche à droite : un dépôt source qui contient le code et les fichiers de workflow, une étape de build et de tests qui installe, compile et teste, et une étape de déploiement qui atteint les registres, le cloud et les clusters. Des secrets comme les jetons, les clés cloud et les clés de publication sont conservés dans l’environnement de build.
Trois attaques entrent par des points différents. Attaque 1 : un jeton volé ajoute un faux fichier de workflow dans le dépôt. Attaque 2 : un paquet de confiance exécute du code au moment de l’installation pendant le build. Attaque 3 : une faille du système de CI lui-même, par exemple GitLab ou Argo CD, est exploitée sur le serveur de CI.
Les trois attaques mènent aux secrets ; c’est pourquoi les secrets de l’environnement de build constituent la cible commune.
Schéma 1 : un jeton volé ajoute un faux workflow (GhostAction)
GitHub Actions exécute votre pipeline à partir de fichiers de workflow stockés dans le dépôt, sous .github/workflows/. Toute personne qui peut écrire dans le dépôt peut en ajouter un. C’est la faiblesse qu’exploite GhostAction.
La campagne a été signalée pour la première fois en septembre 2025. GitGuardian recense une vague en août 2026, et l’activité de cette quinzaine a culminé les 8 et 9 octobre.
Selon StepSecurity, les attaquants ont ajouté aux dépôts un workflow nommé « Security Audit » ou « Github Actions Security ». Il ressemble à un contrôle utile. Il s’exécute à chaque push et envoie des données à l’adresse d’un serveur codée en dur.
L’ancienne version envoyait les secrets nommés du dépôt. La version d’octobre est allée plus loin. Elle a aussi fouillé les fichiers de travail et tout l’historique git à la recherche d’environ 13 types d’identifiants, comme des clés cloud, de services d’IA et de logiciels en tant que service (SaaS). Le conseil de StepSecurity est clair : supprimer un secret de la branche actuelle ne sert à rien, car l’historique est lui aussi analysé.
Comment les attaquants ont-ils obtenu l’accès en écriture ? StepSecurity indique que ce point n’est pas confirmé pour les comptes d’octobre. La source la plus probable est constituée de jetons d’accès personnels divulgués par des logiciels malveillants voleurs d’identifiants ou par des fuites de données. Dans un cas, le compte compromis pouvait écrire dans le dépôt d’une grande entreprise, si bien que le nouveau workflow y est entré sans revue.
Il existe deux séries de chiffres, et elles ne mesurent pas la même chose :
- StepSecurity a dénombré 345 dépôts touchés lors de deux balayages le 8 octobre. Environ 378 dépôts avaient le workflow malveillant actif le 9 octobre.
- GitGuardian, dans sa mise à jour du 13 octobre, indique qu’environ 1 900 comptes ont été compromis. Selon lui, plus de 30 000 dépôts ont été ciblés, et la campagne a tenté d’extraire 3 174 secrets. Il s’agit de cibles et de tentatives, non de vols confirmés, et GitGuardian ne donne aucun chiffre sur les secrets réellement dérobés en octobre.
GitGuardian rapporte également que GitHub a commencé à bloquer le workflow malveillant à partir du 9 octobre, et que les vagues des 10 et 12 octobre n’ont extrait aucun secret. C’est GitGuardian qui le rapporte, et GitHub n’est pas cité à ce sujet ici.
GitGuardian note que certaines victimes ont été touchées en 2025 comme en 2026, ce qui laisse penser que les secrets de la première vague n’ont jamais été renouvelés. Il avertit aussi que renouveler les secrets volés ne suffit pas. Vous devez retrouver et révoquer l’identifiant GitHub qui a servi à ajouter le workflow, faute de quoi quelqu’un pourra s’en servir à nouveau.
GitHub dispose aussi de ses propres protections. Depuis juillet, il met en attente les exécutions de workflow qu’il juge potentiellement malveillantes jusqu’à ce qu’un collaborateur disposant de l’accès en écriture les approuve, sur les dépôts publics de github.com, sans aucune configuration. Ses protections d’exécution des workflows, disponibles pour tous depuis le 17 septembre, vous permettent de définir des règles sur qui et quoi peut déclencher des workflows. Elles aident, mais elles ne remplacent pas la revue des modifications apportées aux fichiers de workflow.
Schéma 2 : un paquet de confiance exécute du code quand vous l’installez (TensorLake)
La plupart des gestionnaires de paquets peuvent exécuter un petit script lors de l’installation d’un paquet. On les appelle des scripts d’installation. Ils existent pour de bonnes raisons, comme la compilation de code natif. Mais ils s’exécutent aussi sur l’ordinateur portable de vos développeurs et sur votre serveur de build avant que quiconque ait regardé ce qu’ils font.
Le 8 octobre, la version 0.5.144 du paquet tensorlake est apparue sur npm. Selon Aikido, elle embarquait une variante du ver Shai-Hulud, une famille de logiciels malveillants voleurs d’identifiants déjà observée auparavant. StepSecurity parle aussi d’un ver et décrit le même comportement. Son script preinstall téléchargeait un environnement d’exécution JavaScript et lançait une charge utile obfusquée. Cette charge utile recherchait des variables d’environnement, des identifiants cloud et Kubernetes, des clés SSH et des données de navigateur.
Deux détails comptent pour les défenseurs.
D’abord, le paquet disposait d’une attestation de provenance npm valide. La provenance est un enregistrement signé qui indique où et comment un paquet a été construit. StepSecurity rapporte que les attaquants ont poussé leur code directement sur la branche principale sous l’identité d’un mainteneur, sans pull request.
C’est ensuite le workflow de publication du projet lui-même qui a construit et publié le paquet. La provenance disait vrai sur le lieu de construction. Elle ne pouvait pas vous dire que le code était sûr.
Ensuite, le logiciel malveillant comportait ce que StepSecurity appelle un « jeton otage » (hostage token). Il vérifie le jeton GitHub volé toutes les 60 secondes pendant 24 heures au maximum et, si GitHub rejette le jeton, il supprime le répertoire personnel. Après un vol, le conseil habituel est de révoquer d’abord le jeton, mais ici cela pourrait déclencher les dégâts.
StepSecurity recommande de supprimer le service de surveillance du logiciel malveillant, après avoir fait une sauvegarde, avant de révoquer quoi que ce soit.
Les autres conseils sont plus simples. Épinglez la dernière version saine, 0.5.143. Désactivez les scripts d’installation. Renouvelez tous les identifiants auxquels la machine avait accès, et reconstruisez toute machine dont vous ne pouvez pas prouver qu’elle est saine.
StepSecurity a constaté que la version 0.5.144 pouvait encore être téléchargée au moment de la rédaction de son rapport. Le registre npm ne répertorie plus cette version (vérifié le 19 octobre), et le paquet est passé à des versions ultérieures.
Il y a aussi une bonne nouvelle. npm 12, mis à la disposition de tous par GitHub le 8 juillet 2026, désactive par défaut les scripts d’installation, et il bloque les dépendances git et par URL distante sauf si vous les autorisez. Cela bloque l’étape dont dépendait cette attaque. Cela n’aide toutefois que si votre pipeline exécute réellement npm 12 ou une version ultérieure, et non une version plus ancienne figée dans une image de build épinglée.
Schéma 3 : une faille dans le système de CI lui-même (GitLab et Argo CD)
Le troisième schéma est différent. Personne ne trompe le pipeline. C’est le logiciel qui exécute le pipeline qui présente un bogue.
GitLab. Le 12 octobre, GitLab a publié les versions 19.4.2, 19.3.5 et 19.2.8 pour corriger CVE-2026-97229. Cette vulnérabilité a le score de gravité le plus élevé possible, CVSS 10,0. Le titre de l’avis de GitLab décrit un dépassement d’entier dans le compilateur d’expressions régulières utilisé pour la configuration CI/CD, et GitLab indique que, dans certaines conditions, elle pourrait permettre à un utilisateur non authentifié d’exécuter du code sur le serveur.
GitLab.com est déjà corrigé, et tous les locataires (tenants) GitLab Dedicated ont été corrigés avant la publication. GitLab recommande vivement aux installations autogérées de se mettre à jour immédiatement.
Le score suppose l’absence de connexion, mais Rapid7 a relevé une condition. L’attaquant doit pouvoir commiter un fichier .gitlab-ci.yml spécialement conçu et un chemin de dépôt au nom particulier dans une branche d’un projet public. Un compte ordinaire peut remplir cette condition sur les instances où les utilisateurs sont autorisés à créer des projets publics.
Rapid7 a reproduit l’exécution de code sur une version 19.4.1 non corrigée et publié une preuve de concept. À la date de sa mise à jour du 16 octobre, aucune attaque réelle n’avait été confirmée.
Argo CD. Argo CD est un outil qui déploie des applications sur Kubernetes à partir d’un dépôt git. Ses mainteneurs ont publié des correctifs dans les versions 3.5.4, 3.4.10 et 3.3.15 le 6 octobre. L’un des problèmes est CVE-2026-55797, une injection de commandes dans le repo server via l’URL de proxy d’un dépôt, sur les dépôts git SSH, notée 8,8.
Les notes de version recensent huit correctifs de sécurité au total, dont quatre jugés critiques. Ils portent notamment sur des moyens d’exécuter des commandes ou de lire des fichiers sur le serveur de dépôts, et sur un moyen de contourner les restrictions de projet. Aucune attaque n’a été signalée pour aucun d’entre eux. Si vous exploitez Argo CD, lisez les notes de version et mettez à jour.
Aucun de ces deux cas ne constitue une preuve d’attaque. Ils comptent parce que les systèmes qui exécutent votre pipeline disposent des mêmes pouvoirs que votre pipeline.
Ce que les trois schémas ont en commun
Chaque attaque a emprunté un chemin différent. GhostAction est passé par un jeton volé et un fichier de workflow. TensorLake est passé par un paquet que votre build installe. Avec GitLab et Argo CD, l’attaque passerait par la plateforme.
Toutes aboutissent aux secrets de l’environnement de build. C’est le point commun. Les contrôles conçus pour protéger le code applicatif, comme la revue de code et l’analyse des vulnérabilités de vos dépendances, ne couvrent pas ce point à eux seuls. Le pipeline a besoin de sa propre protection.
Jusqu’où approfondir le sujet
Connaître. Tout développeur devrait comprendre que le pipeline est une cible, ce qu’est un secret et pourquoi l’installation d’un paquet peut exécuter du code. Vous n’avez rien à configurer.
Appliquer. Les ingénieurs plateforme et DevOps qui écrivent ou relisent des workflows ont besoin des compétences pratiques : limiter les permissions des jetons, protéger les fichiers de workflow, désactiver les scripts d’installation, restreindre l’accès réseau des runners de build et renouveler les secrets dans le bon ordre.
Maîtriser. Les responsables de la sécurité des pipelines doivent concevoir en partant de l’hypothèse d’une défaillance. Ils décident de la manière dont les secrets sont émis, de leur durée de vie, et de la façon dont un build compromis serait confiné puis reconstruit.
Une vérification d’une heure
Vous pouvez faire l’essentiel de ce qui suit en une heure. Commencez par les points qui ne coûtent rien.
- Vérifier qui peut modifier les fichiers de workflow. Assurez-vous que les modifications de
.github/workflows/exigent une revue, par exemple avec une règle de code owners et une protection de branche. Pour voir quand des fichiers de workflow ont été ajoutés, exécutezgit log --all --diff-filter=A --name-only -- .github/workflows. Repérez les noms que vous ne reconnaissez pas, comme un « security audit » que vous n’avez jamais demandé. - Vérifier la portée des jetons. Utilisez des jetons à granularité fine (fine-grained), avec la durée de vie la plus courte et le moins de dépôts possible. Réglez les
permissionspar défaut du jeton de workflow en lecture seule, et élargissez-les uniquement là où un job a besoin de plus. - Vérifier les scripts d’installation. Exécutez
npm --versiondans la même image que celle qu’utilise votre pipeline. Si la version est antérieure à 12, définissezignore-scripts=truedans.npmrcet n’autorisez que les paquets qui ont réellement besoin d’un script. - Vérifier ce que le build peut atteindre. Si vos runners peuvent envoyer des données vers n’importe quelle adresse sur Internet, un secret volé sort facilement. N’autorisez que les destinations dont le build a besoin.
- Connaître votre ordre de renouvellement. Si vous devez renouveler des identifiants, commencez par ceux qui permettent de publier ou de déployer (registre de paquets, registre de conteneurs, rôles de déploiement cloud), puis les accès cloud et aux clusters, puis tout le reste. Après un paquet malveillant, lisez d’abord les étapes de suppression publiées par l’éditeur.
- Vérifier votre propre système de CI. Si vous hébergez vous-même GitLab ou Argo CD, confirmez que vous utilisez une version corrigée.
Ce que vous pouvez ignorer pour l’instant
Vous n’avez pas besoin de suivre chaque preuve de concept ni d’apprendre le fonctionnement interne de chaque famille de logiciels malveillants. Les détails changent d’une semaine à l’autre, mais pas les vérifications ci-dessus.
Vous n’avez pas non plus besoin d’abandonner les vérifications de provenance à cause de TensorLake. Elles vous indiquent où un paquet a été construit, ce qui reste utile. Simplement, ne les considérez pas comme une garantie que le code est sûr.
Que faire ensuite
Choisissez un dépôt et suivez la liste de vérification. Commencez par la revue des fichiers de workflow et la portée des jetons : cela ne coûte rien et ferme la porte utilisée par GhostAction.
Si vous ne devez examiner qu’une seule chose dans votre propre configuration cette semaine, découvrez quels secrets votre build peut atteindre et depuis combien de temps ils existent.
Le pipeline fait partie de votre surface d’attaque. Protégez-le comme la production.
Pour aller plus loin
- StepSecurity, GhostAction Returns
- GitGuardian, GhostAction Returns
- GitHub, GitHub Actions holds potentially malicious workflows for approval et Workflow execution protections generally available
- Aikido, tensorlake NPM package compromised with Shai Hulud worm
- StepSecurity, Tensorlake npm package compromised: a worm with a hostage token
- GitHub, npm install-time security and GAT bypass-2FA deprecation
- GitLab, Critical patch release 19.4.2, 19.3.5, 19.2.8
- Rapid7, CVE-2026-97229: Critical unauthenticated remote code execution in GitLab
- Argo CD, notes de version v3.5.4 et avis GHSA-j6cw-g6p4-7hch
- npm, métadonnées du paquet tensorlake, où la version 0.5.144 n’est plus répertoriée (vérifié le 19 octobre 2026)
Pour une lecture complémentaire, consultez GitHub Actions évolue (en anglais), qui traite d’un autre changement de plateforme touchant les pipelines.
