Intégration continue et déploiement continu (CI/CD) pipelineLes s jouent un rôle central dans la facilitation du développement rationalisé de logiciels. Pourtant, comme ces pipelineAlors que la protection contre les vulnérabilités devient de plus en plus cruciale, l'impératif de les protéger devient plus pressant. Cette enquête approfondie se concentre sur la gestion d'un risque majeur identifié dans le Top 10 de l'OWASP. CI/CD Risques de sécurité : Empoisonné Pipeline Exécution (EPI).
Qu'est-ce qui est empoisonné Pipeline Exécution (EPI)
Selon le Top 10 de l'OWASP CI/CD Risques de sécurité, «Empoisonné Pipeline Internationaux (EPI) le risque fait référence à la capacité d'un attaquant ayant accès aux systèmes de contrôle de source – et sans accès à l'environnement de construction – pour manipuler le processus de build en injectant du code/des commandes malveillants dans la build pipeline paramétrage, essentiellement "empoisonner" le pipeline et exécuter du code malveillant dans le cadre du processus de construction »
En quelques mots, Empoisonné Pipeline L'exécution (EPI) est produite lorsque l'attaquant peut modifier le pipeline logique.
Il y en a deux variantes:
- EPI direct (D-EPI) : Dans un scénario D-PPE, l'attaquant modifie le fichier de configuration CI dans un référentiel auquel ils ont accès, soit en poussant la modification directement vers une branche distante non protégée sur le dépôt, soit en soumettant un PR avec la modification depuis une branche ou un fork. Depuis l'IC pipeline l'exécution est définie par les commandes dans le fichier de configuration CI modifié, les commandes malveillantes de l'attaquant s'exécutent finalement dans le nœud de build une fois la build terminée. pipeline est déclenché.
- EPI indirect (I-EPI): Dans certains cas, la possibilité d'un D-PPE n'est pas disponible pour un adversaire ayant accès à un SCM référentiel (par exemple si le pipeline est configuré pour extraire le fichier de configuration CI d'une branche distincte et protégée dans le même référentiel). Dans un tel scénario, plutôt que d'empoisonner le pipeline lui-même, un attaquant injecte du code malveillant dans les fichiers référencés par le pipeline (par exemple : scripts référencés depuis le pipeline fichier de configuration)
Dans les deux cas, GitHub exécutera le fichier modifié pipeline sans avoir besoin d’un examen ou d’une approbation préalable.
Détection précoce des EPI
Comment détecter ce type de vulnérabilité ?
Voyons cet exemple pipeline :
name: PR CI
on:
pull_request:
branches: [ main ]
env:
MY_SECRET: ${{ secrets.MY_SECRET }}
jobs:
pr_build_test_and_merge:
runs-on: ubuntu-latest
steps:
# checkout PR code
- name: Checkout repository
uses: actions/checkout@v4
# Simulation of a compilation
- name: Building ...
run: |
echo $MY_SECRET
mkdir ./bin
touch ./bin/mybin.exe
# Simulation of running tests
- name: Running tests ...
id : run_tests
run: |
echo Running tests..
chmod +x runtests.sh
./runtests.sh "${{ github.event.pull_request.user.login }}" "${{ github.workflow }}"
echo Tests executed.
Et le contenu d'un script shell factice (runtests.sh) :
#!/usr/bin/bash
echo "Executing Tests script [from user $1 at $2]" >> runtests.out
exit 0
Le pipeline est assez simple : son objectif est de fournir au réviseur quelques indications préliminaires pour la Pull Request Processus d'acceptation (PR) :
- Il sera déclenché le pull_request (c'est-à-dire chaque fois qu'un PR est créé)
- Il extrait le code PR (c'est-à-dire le code contribué)
- Cela fera la construction
- Il exécutera des tests sur le code contribué (par exemple en exécutant un script shell)
Les étapes n°3 (créer la construction) et n°4 (exécuter le test) échoueront si le code ne se compile pas ou s'il ne réussit pas les tests. Ces étapes constituent donc une condition nécessaire, mais pas suffisante, pour accepter le PR. En cas de succès, l'administrateur du dépôt procédera à l'examen du code contribué et, sur cette base, il acceptera/rejetera/commentera le PR.
Scanner Xygeni
Xygéni fournit une CLI (le "Scanner Xygeni") qui peut être intégré dans un pipeline ou exécutez-le dans une ligne de commande. Le Xygeni Scanner traitera le pipelines pour vérifier les vulnérabilités et, si un GitHub PAT est fourni, il se connectera à GitHub pour découvrir les vulnérabilités au niveau de l'organisation/du dépôt.
Inventaire Xygeni
Lorsque nous exécutons Xygeni Scanner sur ce dépôt, il découvre un ensemble d'actifs utiles (le Inventaire Xygeni). L'inventaire sera rempli de nombreux types différents de CI/CD actif, Tels que:
- Le SCM Système où le dépôt est stocké
- Le SCM Plugins installé/utilisé
- Le Référentiel de codes lui-même
- Le SCM Organisation où appartient le dépôt
- Le CI/CD Pipelines et emplois
- Le CI/CD Système exécuter le pipelines
- IaC Ressources défini dans le dépôt
- Externe Dépendances
- etc..
Dans notre exemple, nous pouvons filtrer l'inventaire par type d'actif spécifique (SCM- et les actifs liés au CICD), nous pouvons donc voir que :
- SCM le système est GitHub Cloud
- Le dépôt est stocké dans GitHub Cloud et appartient à une organisation GitHub spécifique
- Il y en a deux pipelines propulsé par GitHub (CI/CD système)
- Chaque pipeline contient une étape spécifique
En sélectionnant ci-dessus pipeline nous pouvons voir quelques vulnérabilités:
- At pipeline niveau, il est vulnérable à la fois direct et gratuit et EPI indirect.
Nous pouvons voir les détails de ces empoisonnés Pipeline Vulnérabilités d'exécution
Xygeni détecte que c'est vulnérable au D-EPI parce qu'il est déclenché sur un Pull Request événement et il n'y a pas de contrôles de sécurité supplémentaires, donc tout utilisateur du référentiel peut modifier le pipeline et ces modifications seront exécutées sans aucun examen ou approbation.
Dans le même sens, Xygeni détecte également qu'il s'agit vulnérable à l'I-PPE à cause de l'appel au script shell depuis le pipeline: tout utilisateur du dépôt peut modifier le script shell et ces modifications seront exécutées sans aucune révision ni approbation.
Voulez-vous en savoir plus?
Exploiter les EPI
Pour exploiter l'EPI, considérons un scénario dans lequel il y a deux types d'utilisateurs de dépôt:
- An utilisateur interne (un développeur interne travaillant sur ce dépôt), avec des autorisations d'écriture sur le dépôt
- An utilisateur externe (un développeur externalisé travaillant sur ce dépôt mais avec des autorisations de lecture sur le dépôt), c'est-à-dire non autorisé à créer une branche sur le dépôt et obligé de travailler sur un fork.
Imaginons que les deux soient des attaquants malveillants (ou usurpés par un acteur malveillant). Le dépôt contient un secret et les deux veulent voler le secret du repo et envoyez-le à un serveur contrôlé par des pirates. Pour ce faire, ils profiteront des Empoisonnés Pipeline Vulnérabilités d'exécution du pipeline.
Dans les deux cas (utilisateur externe et interne), ils ouvrent un Pull Request avec les mêmes modifications :
- Le pipeline et le script shell sont modifiés à lire le secret de l'environnement et envoyez-le à un serveur contrôlé par des pirates
Les modifications pourraient être les suivantes :
Les deux utilisateurs créeront un Pull Request avec les modifications. Dès la création du PR, GitHub exécutera les deux modifications (sans avoir besoin d'un examen ou d'une approbation préalable), ce qui donne ce qui suit :
Idem pour les utilisateurs en écriture et en lecture, dans les deux cas, D-PPE et I-PPE sont exécutés, à la différence que l'utilisateur en lecture n'est pas en mesure d'accéder aux secrets. (!!!!)
Cette raison est parce que, dans le cas d'un PR provenant d'un fork, GitHub ne permet pas l'accès aux secrets du repo. Bien que l'utilisateur lu ne puisse pas lire les secrets, il peut toujours exécuter n'importe quel autre programme. Un exemple d'attaque typique consiste à créer des PR qui téléchargent un mineur de crypto, de sorte que le programme d'exécution GitHub exécutera le mineur de crypto lors de l'exécution d'un mineur de crypto. pipeline.
Ce n’est pas un environnement sûr, bien sûr !! Que pourrait faire l’administrateur du dépôt pour l’éviter ?
Après quelques recherches sur Google, l'administrateur du dépôt décide de modifier le pipeline être déclenché sur un pull_request_target événement. Pourquoi? Parce que pipelines déclenchés sur pull_request_target ne permettent pas l'exécution pipeline modifications, c'est à dire malgré toute modification utilisateur l'"original" pipeline sera exécuté.
En suivant notre exemple, l'attaque sera la même que précédemment. Que se passera-t-il après cela pipeline modification?
Comme prévu, Le D-PPE n'est pas exécuté mais comme l'I-PPE est toujours là, l'utilisateur lu peut désormais accéder au secret du dépôt !!!
Quelle est la raison pour laquelle l’utilisateur lu a désormais accès aux secrets ? Bien que le pipeline ne peut pas être modifié, il est toujours possible de modifier le script shell. Quand un pipeline est déclenché sur pull_request_target, il sera exécuté en mode privilégié so ce sera aussi le script shell, ce qui permet au script shell d'accéder aux secrets du dépôt !!
Mesures préventives
GitHub fournit certaines mesures pour se protéger contre les PR malveillants.
Règles de protection des succursales
Avec GitHub, vous pouvez définir des règles de protection des branches sur les branches sélectionnées.
Pour vos branches protégées, vous pouvez spécifier une stratégie qui nécessite un pull request avant de fusionner (ainsi que des conditions supplémentaires telles qu'un nombre requis d'approbations, des avis des propriétaires de codes, etc. )
Quelques conditions qui méritent une attention particulière sont :
- "Autoriser les acteurs spécifiés à contourner les exigences pull requests ».
- "Ne pas autoriser le contournement des paramètres ci-dessus »
Alors que la plupart des conditions renforcent la rigueur de la politique, celles-ci l'assouplissent, ce qui pourrait ouvrir la porte à des activités malveillantes, par exemple dans le cas où des informations d'identification seraient volées par des acteurs « privilégiés ».
Restreindre les autorisations GITHUB_TOKEN (moindre privilège)
Restreindre les autorisations du jeton GitHub uniquement à celles requises ; de cette façon, même si les attaquants réussissent à compromettre votre pipeline, ils ne pourront pas faire grand-chose.
Évitez l'interpolation de chaîne en utilisant pipeline variables d'environnement
Chaque fois que vous utilisez des variables d'entrée dans votre pipeline, sachez qu’elles doivent être considérées par défaut comme des données « non fiables » (leur contenu est contrôlé par l’utilisateur final). Voir Actions et flux de travail non fiables sécurisés et Apprenez les actions Github.
Vous devez toujours utiliser des variables d'environnement pour insérer des variables d'entrée dans des scripts au lieu d'utiliser l'interpolation de chaîne.
Exécutions du workflow et exigences d’approbation
Pour public repos, GitHub permet de spécifier comment travailler avec des PR « externes ».
Les paramètres de l'organisation GitHub (« Org >> Paramètres >> Actions >> Général ») permettent de spécifier comment gérer les PR externes :
Par défaut, GitHub exigera l'approbation des relations publiques pour les nouveaux contributeurs, ce qui compliquera les attaques de requêtes malveillantes. Malgré tout, l'attaquant pourrait gagner la confiance des responsables du projet, par exemple en contribuant à des contributions innocentes. pull request avant la véritable attaque.
En ce sens, le La troisième option (exiger l'approbation de tous les collaborateurs externes) ajoute un niveau de contrôle plus élevé.
Pour Privé repos, GitHub fournit également un contrôle utile au niveau de l'organisation et du dépôt.
"Exécutez des flux de travail à partir de Pull Requests» (non coché par défaut) permet aux utilisateurs d'exécuter des workflows à partir de PR fork (en utilisant un GITHUB_TOKEN avec des autorisations en lecture seule et sans accès aux secrets). En sélectionnant cette option avec la dernière («Exiger l'approbation pour les flux de travail des fork PR"), vous pouvez atteindre une politique similaire aux pensions privées (comme indiqué ci-dessus).
Comme nous l'avons vu dans l'exploit PPE d'un utilisateur en lecture, permettre l'exécution de workflows à partir d'un fork pull requests c'est dangereux !!
Les options restantes («Envoyer des jetons d'écriture aux workflows depuis le fork pull requests" et "Envoyer des secrets et des variables aux workflows depuis for pull requests») diminuer le niveau de sécurité appliqué aux PR fork.
Vous pouvez définir cette stratégie de fork soit au niveau de l'organisation, soit au niveau du dépôt. Si la stratégie est désactivée au niveau de l'organisation, elle ne peut pas être activée au niveau du dépôt. Mais si la stratégie est activée au niveau de l’organisation, elle peut être désactivée au niveau du dépôt.
Récap
Nous espérons que vous avez vu les implications d'avoir certains pipeline vulnérable à Empoisonné Pipeline Exécution. C'est trop facile de commit un vulnérable pipeline, et il est difficile d'en écrire un en toute sécurité.
Il est donc très utile d'utiliser le scanner Xygeni pour être conscient de ces vulnérabilités.
Vous ne pouvez pas résoudre une vulnérabilité à moins d'être conscient de son existence !!
Mais… Il reste encore une question en suspens… Comment éviter l'I-EPI ?
Ce sera le sujet de notre prochain post 🙂… Empoisonné indirect Pipeline Exécution (I-PPE) !!





