Gh Actions - Context Script Injections

Reading time: 5 minutes

tip

Apprenez et pratiquez le hacking AWS :HackTricks Training AWS Red Team Expert (ARTE)
Apprenez et pratiquez le hacking GCP : HackTricks Training GCP Red Team Expert (GRTE) Apprenez et pratiquez le hacking Azure : HackTricks Training Azure Red Team Expert (AzRTE)

Soutenir HackTricks

Comprendre le risque

GitHub Actions évalue les expressions ${{ ... }} avant que l'étape n'exécute. La valeur évaluée est insérée dans le programme de l'étape (pour les étapes run, un script shell). Si vous interpolez des entrées non fiables directement dans run:, l'attaquant contrÎle une partie du script shell et peut exécuter des commandes arbitraires.

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 :

  • L'Ă©valuation a lieu avant l'exĂ©cution. Le script 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.). Voir la rĂ©fĂ©rence sur les entrĂ©es non fiables : https://securitylab.github.com/resources/github-actions-untrusted-input/
  • Le quoting du shell Ă  l'intĂ©rieur de run: n'est pas une dĂ©fense fiable, car l'injection se produit lors de l'Ă©tape de rendu du template. Les attaquants peuvent sortir des guillemets 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é lorsqu'une personne 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 un issue avec le titre $(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 suffisent pas :

  • Les expressions sont Ă©valuĂ©es en premier, puis le script rĂ©sultant s'exĂ©cute. Si la valeur non fiable contient $(...), ;, "/', ou des retours Ă  la ligne, elle peut modifier la structure du programme malgrĂ© vos guillemets.

ModÚle sûr (shell variables via env)

Mitigation correcte : copiez l'entrée non fiable dans une variable d'environnement, puis utilisez l'expansion native du shell ($VAR) dans le script d'exécution. Ne la réinjectez pas avec ${{ ... }} dans 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 du template dans la commande et entraĂźne le mĂȘme risque d'injection.
  • PrivilĂ©giez le passage d'entrĂ©es non fiables via le mapping env: et rĂ©fĂ©rencez-les avec $VAR dans run:.

Surfaces déclenchables par un lecteur (à traiter comme non fiables)

Les comptes avec seulement la permission de lecture sur les dĂ©pĂŽts publics peuvent quand mĂȘme dĂ©clencher de nombreux Ă©vĂ©nements. Tout champ 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 (les organisations peuvent restreindre les discussions)
  • pull_request, pull_request_review, pull_request_review_comment
  • pull_request_target (dangereux s'il est mal utilisĂ©, s'exĂ©cute dans le contexte du dĂ©pĂŽt de base)
  • fork (n'importe qui peut forker des dĂ©pĂŽts publics)
  • watch (le fait d'ajouter une Ă©toile Ă  un dĂ©pĂŽt)
  • Indirectement via des chaĂźnes workflow_run/workflow_call

Les champs spécifiques contrÎlés par un attaquant dépendent de l'événement. Consultez le guide de GitHub Security Lab sur les entrées non fiables : https://securitylab.github.com/resources/github-actions-untrusted-input/

Conseils pratiques

  • Minimisez l'utilisation d'expressions dans run:. PrivilĂ©giez 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 lors de l'interpolation de branch names, PR titles, usernames, labels, discussion titles et PR head refs dans des scripts, des options en ligne de commande ou des chemins de fichiers.
  • Pour les reusable workflows et composite actions, appliquez le mĂȘme schĂ©ma : mappez vers env puis rĂ©fĂ©rencez $VAR.

Références

tip

Apprenez et pratiquez le hacking AWS :HackTricks Training AWS Red Team Expert (ARTE)
Apprenez et pratiquez le hacking GCP : HackTricks Training GCP Red Team Expert (GRTE) Apprenez et pratiquez le hacking Azure : HackTricks Training Azure Red Team Expert (AzRTE)

Soutenir HackTricks