GitHub Actions est devenu l’une des plateformes CI/CD les plus largement adoptées. Sa flexibilité, son intégration étroite avec les dépôts GitHub et son riche écosystème en font un choix attractif pour les équipes de toutes tailles.
Parallèlement, les runners GitHub Actions sont apparus comme une surface d’attaque critique dans les attaques modernes contre la chaîne d’approvisionnement logicielle.
Les runners exécutent du code non fiable, manipulent des secrets sensibles et opèrent souvent avec des permissions étendues sur les dépôts, les registres d’artefacts et les environnements cloud.
Cet article explique le fonctionnement des runners GitHub Actions, pourquoi ils sont fréquemment ciblés par les attaquants, et comment concevoir des architectures de runners qui réduisent significativement les risques sans perturber les workflows des développeurs.
Qu’est-ce qu’un runner GitHub Actions ?
Un runner est l’environnement d’exécution dans lequel les workflows GitHub Actions s’exécutent réellement. Chaque job d’un workflow est exécuté sur un runner.
Du point de vue de la sécurité, les runners sont le composant le plus sensible de l’architecture GitHub Actions car ils :
- Exécutent du code arbitraire provenant des workflows
- Traitent le contenu des dépôts et les dépendances
- Accèdent aux secrets et aux tokens
- Produisent les artefacts de build
Si un runner est compromis, l’attaquant peut être en mesure de :
- Exfiltrer des secrets
- Modifier les résultats de build
- Persister entre les jobs ou les workflows
- Se déplacer latéralement vers d’autres systèmes
Types de runners GitHub Actions
Comprendre la sécurité des runners commence par comprendre les types de runners. GitHub Actions prend en charge plusieurs modèles de runners, chacun avec des caractéristiques de confiance et de risque différentes.
Runners hébergés par GitHub
Les runners hébergés par GitHub sont gérés par GitHub et fournis sous forme de machines virtuelles éphémères. Chaque job s’exécute généralement sur une VM neuve qui est détruite après l’exécution.
Caractéristiques de sécurité :
- Éphémères par défaut
- Isolation forte entre les jobs
- Pas d’état persistant entre les exécutions
- Personnalisation limitée
Du point de vue de la sécurité, les runners hébergés par GitHub offrent une base solide pour les charges de travail non fiables telles que les pull requests.
Cependant, ils ne sont pas sans risque. L’exposition des secrets, l’utilisation abusive des permissions et la logique de workflow malveillante peuvent toujours conduire à une compromission.
Runners self-hosted
Les runners self-hosted s’exécutent sur une infrastructure gérée par l’organisation : machines virtuelles, serveurs physiques ou conteneurs.
Ils sont souvent utilisés pour :
- Accéder aux ressources internes
- Utiliser des outils ou environnements personnalisés
- Optimiser les performances ou les coûts
Du point de vue de la sécurité, les runners self-hosted introduisent des risques significatifs :
- Persistance entre les jobs
- État partagé entre les workflows
- Accès réseau aux systèmes internes
- Rayon d’impact plus élevé en cas de compromission
Sans une isolation forte, un seul job compromis peut affecter les builds futurs ou d’autres dépôts.
Runners self-hosted éphémères
Les runners self-hosted éphémères combinent la flexibilité des runners self-hosted avec les avantages sécuritaires de l’éphémérité.
Chaque job s’exécute sur un runner fraîchement provisionné qui est détruit après la fin de l’exécution.
Ce modèle réduit significativement :
- Le risque de persistance
- La contamination inter-jobs
- La compromission de longue durée
Du point de vue de la sécurité, les runners self-hosted éphémères sont fortement préférés aux runners persistants.
Pourquoi les runners sont une cible privilégiée
Les runners se situent à l’intersection des entrées non fiables et des opérations privilégiées. Cela en fait des cibles attractives pour les attaquants.
Les runners exécutent du code non fiable
Les workflows peuvent exécuter du code provenant de :
- Pull requests
- Branches de fonctionnalité
- Dépendances
- Actions tierces
N’importe laquelle de ces sources peut être influencée par un attaquant. Si du code non fiable s’exécute sur un runner disposant de secrets ou de permissions élevées, la compromission est immédiate.
Les runners ont souvent accès aux secrets
Les secrets sont couramment exposés aux runners via des variables d’environnement.
Si les conditions du workflow sont mal configurées, les secrets peuvent être accessibles par :
- Les pull requests issues de forks
- Les contributeurs non fiables
- Les actions tierces malveillantes
Une fois qu’un secret est exposé, il est souvent difficile de le détecter ou de le contenir.
Les runners peuvent influencer les artefacts et les releases
Les runners compilent et empaquettent les artefacts logiciels.
Si un attaquant modifie le résultat du build, l’artefact résultant peut être distribué avec une confiance totale en aval.
Sans vérifications d’intégrité des artefacts, il peut être impossible de détecter la compromission.
Scénarios d’attaque courants liés aux runners
La modélisation des menaces sur les runners révèle des schémas d’attaque récurrents.
Scénario 1 : Abus de pull request
Un attaquant soumet une pull request qui modifie la logique du workflow ou introduit des étapes de build malveillantes.
Si le workflow expose des secrets ou des tokens privilégiés aux builds de PR, l’attaquant peut exfiltrer les identifiants.
Cette attaque ne nécessite aucune vulnérabilité — seulement une mauvaise configuration de la confiance.
Scénario 2 : Compromission d’une action tierce
Les workflows utilisent fréquemment des actions tierces.
Si une action est compromise en amont ou référencée sans épinglage sur un commit spécifique, l’attaquant peut injecter un comportement malveillant dans les workflows.
Le runner exécute l’action avec les mêmes permissions que le code de workflow interne.
Scénario 3 : Compromission d’un runner self-hosted persistant
Sur les runners self-hosted persistants, un attaquant peut :
- Installer des backdoors
- Modifier les outils locaux
- Empoisonner les caches
- Persister entre les jobs
Les workflows futurs peuvent exécuter du code contrôlé par l’attaquant sans le savoir.
Scénario 4 : Mouvement latéral via l’infrastructure des runners
Les runners self-hosted ont souvent un accès réseau aux systèmes internes ou aux environnements cloud.
Un runner compromis peut être utilisé comme pivot pour attaquer d’autres services internes.
Principes d’architecture de sécurité des runners
Sécuriser les runners GitHub Actions est un problème d’architecture, pas un problème de checklist.
Une sécurité efficace des runners repose sur quelques principes fondamentaux.
1. Traiter les runners comme des environnements d’exécution non fiables
Les runners exécutent des entrées non fiables par conception.
Ils ne devraient jamais être implicitement considérés comme fiables, même s’ils fonctionnent au sein d’une infrastructure interne.
Les secrets, l’accès réseau et les privilèges doivent être limités en conséquence.
2. Préférer l’éphémérité au nettoyage
Tenter de « nettoyer » un runner compromis n’est pas fiable.
Détruire et recréer les runners après chaque job offre une garantie de sécurité bien plus forte.
Les runners éphémères éliminent la persistance et réduisent significativement le temps de séjour de l’attaquant.
3. Appliquer le principe du moindre privilège au niveau du job
Chaque job ne devrait recevoir que les permissions dont il a besoin.
Cela inclut :
- Les permissions sur les dépôts
- Les scopes des tokens
- Les identités cloud
Évitez d’accorder des permissions globales ou des permissions d’écriture par défaut.
4. Séparer les charges de travail fiables et non fiables
Les builds de pull requests, les contributions externes et le code non fiable doivent s’exécuter dans des environnements séparés des jobs de release ou de déploiement fiables.
Cette séparation peut être appliquée via :
- Des pools de runners différents
- Des workflows différents
- Des ensembles de permissions différents
5. Réduire la surface d’attaque des runners
Minimisez ce qui est disponible sur les runners :
- Désactivez les outils inutiles
- Restreignez l’accès réseau sortant
- Limitez l’accès en écriture au système de fichiers
- Évitez les caches de longue durée
Une surface d’attaque réduite limite les options de l’attaquant.
Bonnes pratiques pour sécuriser les runners GitHub Actions
Les pratiques suivantes répondent aux risques les plus courants liés aux runners sans modifier fondamentalement les workflows des développeurs.
Utiliser les runners hébergés par GitHub pour le code non fiable
Pour les pull requests et les contributions externes, les runners hébergés par GitHub offrent une isolation forte et une éphémérité automatique.
Évitez d’exposer des secrets à ces jobs sauf en cas de nécessité absolue.
Adopter les runners self-hosted éphémères pour les charges sensibles
Si des runners self-hosted sont nécessaires, rendez-les éphémères.
Chaque job devrait :
- Provisionner un runner neuf
- Exécuter un seul job
- Être détruit immédiatement après
Ce modèle réduit considérablement le risque de persistance.
Verrouiller explicitement les permissions
Utilisez le modèle de permissions granulaires de GitHub.
Définissez les permissions au niveau du workflow ou du job au lieu de vous appuyer sur les valeurs par défaut.
Examinez les modifications de permissions aussi attentivement que les modifications de code.
Épingler et auditer les actions tierces
Épinglez toujours les actions sur un SHA de commit spécifique.
Évitez d’utiliser des actions qui :
- Ne sont plus maintenues
- Manquent de transparence
- Exécutent une logique inattendue
Traitez les actions comme faisant partie de votre chaîne d’approvisionnement.
Protéger agressivement les secrets
Évitez d’exposer des secrets aux workflows déclenchés par :
- Des dépôts forkés
- Des pull requests non fiables
Préférez les identifiants à durée de vie courte et l’accès basé sur l’identité plutôt que les secrets statiques.
Valider les résultats de build
Ne présumez pas que les artefacts produits par les runners sont fiables.
Utilisez :
- La signature des artefacts
- Les attestations de provenance
- Des portes de vérification avant le déploiement
Cela garantit que des runners compromis ne peuvent pas empoisonner silencieusement les releases.
Place de la sécurité des runners dans une stratégie CI/CD globale
La sécurité des runners est une composante de la sécurité des pipelines, mais elle ne peut pas fonctionner seule.
Elle doit être combinée avec :
- La modélisation des menaces CI/CD
- Les frontières de confiance des pipelines
- L’application des politiques
- La vérification de l’intégrité des artefacts
Sans ces éléments, même des runners bien sécurisés peuvent encore produire des résultats non fiables.
Conclusion
Les runners GitHub Actions sont un puissant outil d’automatisation, mais ils représentent également un environnement d’exécution à haut risque.
Ils exécutent du code non fiable, manipulent des identifiants sensibles et produisent des artefacts auxquels les systèmes en aval font confiance.
Sécuriser les runners nécessite des décisions architecturales : éphémérité, isolation, moindre privilège et séparation explicite des niveaux de confiance.
Les organisations qui traitent les runners comme des environnements d’exécution jetables et non fiables — plutôt que comme une infrastructure de confiance — sont bien mieux positionnées pour se défendre contre les attaques modernes visant les pipelines CI/CD et la chaîne d’approvisionnement.