- GitHub Actions a une structure qui, via la syntaxe
uses:des fichiers de workflow, déclare et exécute les dépendances de paquets, ce qui lui permet d’assurer en pratique le rôle de gestionnaire de paquets - Pourtant, il n’existe aucune des fonctionnalités que proposent par défaut les autres gestionnaires de paquets, comme le lockfile, le hash d’intégrité, le pinning des dépendances transitives et la visibilité de l’arbre des dépendances
- Selon la recherche, la plupart des utilisateurs de GitHub Actions exécutent du code externe non vérifié, et des vulnérabilités d’injection de code ont été trouvées dans des milliers de workflows
- Bien que GitHub ait introduit quelques mesures d’atténuation (releases immuables, politique de pinning SHA, etc.), les problèmes de dépendances transitives et de reproductibilité restent encore non résolus
- Ces défauts structurels affectent la sécurité globale de la chaîne d’approvisionnement logicielle et le même problème se propage aussi aux autres systèmes CI fondés sur GitHub Actions
Structure de gestion des paquets et problèmes de GitHub Actions
- Une syntaxe comme
uses: actions/checkout@v4est une déclaration de dépendance, que GitHub interprète pour télécharger et exécuter- C’est le même comportement que celui d’un gestionnaire de paquets classique, mais en l’absence de lockfile, une version différente peut être choisie à chaque exécution
- Comparé à d’autres gestionnaires de paquets (npm, Cargo, NuGet, etc.), Actions n’offre aucune fonctionnalité, comme le lockfile, le pinning transitif, la vérification d’intégrité, la visibilité de l’arborescence des dépendances ou la spécification d’interprétation
- L’absence du lockfile est le problème central, car l’interprétation des dépendances peut changer à chaque exécution, ce qui provoque des builds non déterministes
Résultats de recherche et vulnérabilités de sécurité
- Selon la recherche USENIX Security 2022, 99,7 % des dépôts exécutent les Actions de développeurs externes, 97 % sont des auteurs non vérifiés, 18 % sont sans mise à jour de sécurité
- Une étude ultérieure a trouvé des vulnérabilités d’injection de code dans plus de 4 300 workflows sur 2,7 millions
- GitHub Actions ne fournit pas pleinement des propriétés de sécurité CI/CD essentielles comme le contrôle d’admission, le contrôle d’exécution, le contrôle du code et le contrôle d’accès aux secrets
Principales défaillances techniques
- Problème de version variable : une étiquette comme
@v4peut être rebalisée par un mainteneur avec un nouveau commit, ce qui modifie silencieusement le code- Avec un lockfile, il serait possible d’enregistrer quel SHA a été résolu pour cette étiquette
- Opacité des dépendances transitives : les Actions appelées dans une Composite Action ne sont ni visibles ni contrôlables
- Selon la recherche, 54 % des Actions JavaScript comportent des vulnérabilités, dont la plupart surviennent via des dépendances transitives
- Avec l’incident
tj-actions/changed-files, une attaque de fuite de secrets a eu lieu via la mise à jour d’une dépendance transitive
- Absence de vérification d’intégrité : npm ou Cargo enregistrent les hashs pour vérifier les téléchargements, tandis que Actions ne repose que sur la confiance basée sur SHA
- Non-reproductibilité lors des réexécutions : GitHub indique que « lorsqu’une version est forcée, la version la plus récente est récupérée », donc même avec le même workflow, un code différent peut être exécuté
- Non-visibilité de l’arbre des dépendances : il n’existe pas d’équivalent à
npm lsde npm oucargo treede Cargo, donc aucun moyen de voir la structure complète des dépendances - Règles d’interprétation non publiées : l’interprétation des dépendances d’Actions n’est pas documentée, et
ActionManager.csne contient qu’une logique de téléchargement récursif simple
Limitations structurelles supplémentaires
- Absence de registre central : Actions vit dans un dépôt Git, sans fonction de scan de sécurité, détection de malware ou prévention de typosquatting
- Problème d’environnement partagé : plusieurs Action modifient le même
$PATH, donc les résultats changent selon l’ordre d’exécution - Impossible d’exécuter hors ligne : GitHub doit télécharger à chaque fois, donc impossible de l’exécuter sans réseau
- Vulnérabilité du namespace : le nom d’utilisateur GitHub sert de namespace, exposant au détournement de compte ou aux attaques par faute de frappe
- Avec un lockfile et un hash d’intégrité, une modification de code serait détectée par un échec de build
Contexte de conception et effets de propagation
- Le runner Actions est à l’origine basé sur Azure DevOps pour un usage en environnement interne de confiance
- Lorsqu’un tel modèle a été étendu par GitHub au marketplace public, le modèle de confiance n’a pas été redéfini
- C’est pourquoi des fonctions de base comme le lockfile, la vérification d’intégrité, le pinning des dépendances transitives et la visibilité des dépendances sont absentes
- La généralisation de la fonctionnalité de déploiement automatique de paquets basée sur OIDC a fait en sorte que les failles de sécurité de Actions affectent la chaîne d’approvisionnement de l’ensemble du registre de paquets
- GitLab CI a introduit le mot-clé
integritypour la vérification de hash, mais GitHub a mis fin à cette demande avec le statut “no plan” - Les systèmes CI compatibles GitHub comme Forgejo Actions doivent aussi conserver la même structure, donc les défaillances se propagent à l’ensemble de l’écosystème
Propositions d’amélioration et état actuel
- La communauté a demandé la prise en charge du lockfile (issue #2195), mais GitHub l’a fermée en 2022 avec le statut “no plan”
- La recherche de Palo Alto a montré qu’un pinning SHA seul ne permet pas de protéger les dépendances transitives
- Certaines équipes compensent avec mise à jour Dependabot, vendor en interne dans leur propre dépôt, le scanner de sécurité
zizmor, etc. - La solution fondamentale est d’introduire un lockfile enregistrant SHA et hash d’intégrité de toutes les Actions et de leurs dépendances transitives
- Tant que GitHub ne l’adopte pas, il est impossible de garantir la fiabilité de la chaîne d’approvisionnement CI/CD
2 commentaires
Il comprendra peut-être la leçon une fois qu’il se sera fait pirater, voilà tout.
Avis sur Hacker News
Je ne veux pas défendre GHA (GitHub Actions), mais la documentation indique bien qu’il est recommandé d’épingler les SHA de commit pour la stabilité et la sécurité
On peut bricoler soi-même quelque chose qui ressemble à un fichier de lock, mais comme les dépendances transitives ne sont pas contrôlables, ce n’est pas une solution complète
Au final, cela implique de suivre les correctifs de sécurité et de mettre à jour les hash, ce qui explique sans doute pourquoi l’épinglage par hash n’est pas largement utilisé
La plupart des utilisateurs ne voient même pas le problème, et même ceux qui le voient n’utilisent presque jamais les SHA
Personnellement, j’aime bien Actions et j’en maintiens quelques-uns, mais quand on regarde les dépôts publics, 90 % utilisent
@v1, 9 %@v1.2, et seulement 1 % un SHA de commitAvec un minimum d’investissement, GitHub aurait pu proposer une solution de fichier de lock
Il arrive souvent qu’il dépende d’une version précise de Node ou d’une version d’API, si bien qu’il m’est arrivé d’avoir de meilleurs résultats avec @main
On croit obtenir une « version figée », alors qu’en réalité ce n’est pas le cas
Je ne l’ai compris qu’après avoir eu des problèmes à deux reprises — soit il y a un fichier de lock, soit il n’y en a pas
GitHub ne maintient quasiment pas ses propres Actions, et on finit même par dépendre de forks non officiels pour des fonctions de base
L’ensemble de l’écosystème donne l’impression d’être maintenu à coups de rustines
GitHub a en effet annoncé qu’il donnerait la priorité à la migration vers Azure plutôt qu’au développement de fonctionnalités
Article lié
Même notre petite entreprise paie plus de 200 dollars par mois
Cela ressemble à une nouvelle source de revenus jugée plus importante qu’un abonnement Windows
Les auteurs d’origine ont probablement déjà quitté l’entreprise
Je me demande si quelqu’un a déjà utilisé ArgoCD comme pipeline CI
Je pense que GHA est un exemple d’échec de la philosophie « less is more »
Le vrai problème, c’est qu’il est devenu le standard de fait du secteur
Avec un peu d’investissement, on aurait pu avoir un CI bien meilleur, mais on a l’impression que Microsoft répète l’erreur de l’époque d’IE6
Désormais, une jeune génération d’ingénieurs, qui n’a pas de point de comparaison, ne perçoit même plus ses limites
J’envisage de transformer un vieux laptop à la retraite en serveur Woodpecker. J’aimerais voir à quoi ressemble un CI que les gens ne détestent pas
À côté de ça, GHA ne me semble pas apporter grand-chose
Quand l’entreprise a voulu passer de Jenkins/Ansible à GHA, je m’y suis opposé, et avec le recul j’ai l’impression que c’était la bonne décision
Le CI implique toujours une charge de maintenance importante, et l’environnement Mac reste particulièrement pénible à gérer
À la question « faites-vous confiance à GitHub pour fournir le bon code SHA ? »,
vu que la plupart des gens utilisent des runners hébergés par GitHub, si vous ne pouvez pas faire confiance à cela, c’est que vous avez déjà un problème plus grave
Je me demande ce que donnerait GitHub Actions avec une architecture local-first, prenant en charge un locking basé sur Nix
cachix/cloud.devenv.sh
Beaucoup d’Actions tierces référencent directement la branche master dans leur documentation ou leurs exemples
Une seule poussée malveillante pourrait permettre des fuites de données dans d’innombrables dépôts
Même l’usage de tags n’est pas une défense complète, puisqu’ils peuvent être déplacés
En voyant les quatre propriétés de sécurité clés du CI/CD citées par les chercheurs (authentification, exécution, code, accès aux secrets), je me pose une question
Est-ce que le CI/CD a vraiment besoin d’accéder à des secrets ?
À mon avis, disposer uniquement des permissions nécessaires pour appeler des API devrait suffire
Dans un système idéal, il ne manipulerait jamais directement les secrets, mais passerait indirectement par un adaptateur de type enclave sécurisée
En pratique, la plupart des clients ont toujours besoin de secrets
La plateforme doit au minimum fournir un mécanisme de gestion des secrets sûr
C’est particulièrement vrai pour les projets open source qui veulent déployer directement depuis le CI
Je me demande concrètement en quoi l’« approche enclave sécurisée » serait différente
mais en pratique chaque environnement est différent et le coût d’implémentation est élevé, donc la plupart des gens finissent par adopter l’approche conteneur + variables d’environnement
Si l’on veut automatiser ce type de tests, les secrets sont inévitables
S’il faut committer un fichier de lock dans le dépôt, un problème de bootstrapping se pose au moment de sa création initiale
Pour le résoudre, il faudrait pouvoir exécuter Actions en local
Il existe des outils comme nektos/act, mais ils servent surtout au débogage
Il faudrait probablement un mécanisme séparé fondé sur de l’analyse statique